xref: /petsc/src/vec/is/section/interface/section.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
1ea844a1aSMatthew Knepley /*
2ea844a1aSMatthew Knepley    This file contains routines for basic section object implementation.
3ea844a1aSMatthew Knepley */
4ea844a1aSMatthew Knepley 
5ea844a1aSMatthew Knepley #include <petsc/private/sectionimpl.h> /*I  "petscsection.h"   I*/
6ea844a1aSMatthew Knepley #include <petscsf.h>
7ea844a1aSMatthew Knepley 
8ea844a1aSMatthew Knepley PetscClassId PETSC_SECTION_CLASSID;
9ea844a1aSMatthew Knepley 
10ea844a1aSMatthew Knepley /*@
11ea844a1aSMatthew Knepley   PetscSectionCreate - Allocates PetscSection space and sets the map contents to the default.
12ea844a1aSMatthew Knepley 
13ea844a1aSMatthew Knepley   Collective
14ea844a1aSMatthew Knepley 
15ea844a1aSMatthew Knepley   Input Parameters:
16ea844a1aSMatthew Knepley + comm - the MPI communicator
17ea844a1aSMatthew Knepley - s    - pointer to the section
18ea844a1aSMatthew Knepley 
19ea844a1aSMatthew Knepley   Level: beginner
20ea844a1aSMatthew Knepley 
21ea844a1aSMatthew Knepley   Notes:
22ea844a1aSMatthew Knepley   Typical calling sequence
23ea844a1aSMatthew Knepley $       PetscSectionCreate(MPI_Comm,PetscSection *);
24ea844a1aSMatthew Knepley $       PetscSectionSetNumFields(PetscSection, numFields);
25ea844a1aSMatthew Knepley $       PetscSectionSetChart(PetscSection,low,high);
26ea844a1aSMatthew Knepley $       PetscSectionSetDof(PetscSection,point,numdof);
27ea844a1aSMatthew Knepley $       PetscSectionSetUp(PetscSection);
28ea844a1aSMatthew Knepley $       PetscSectionGetOffset(PetscSection,point,PetscInt *);
29ea844a1aSMatthew Knepley $       PetscSectionDestroy(PetscSection);
30ea844a1aSMatthew Knepley 
316aad120cSJose E. Roman   The PetscSection object and methods are intended to be used in the PETSc Vec and Mat implementations; it is
32ea844a1aSMatthew Knepley   recommended they not be used in user codes unless you really gain something in their use.
33ea844a1aSMatthew Knepley 
34db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionDestroy()`
35ea844a1aSMatthew Knepley @*/
36*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreate(MPI_Comm comm, PetscSection *s) {
37ea844a1aSMatthew Knepley   PetscFunctionBegin;
38ea844a1aSMatthew Knepley   PetscValidPointer(s, 2);
399566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
40ea844a1aSMatthew Knepley 
419566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*s, PETSC_SECTION_CLASSID, "PetscSection", "Section", "IS", comm, PetscSectionDestroy, PetscSectionView));
42ea844a1aSMatthew Knepley 
43ea844a1aSMatthew Knepley   (*s)->pStart              = -1;
44ea844a1aSMatthew Knepley   (*s)->pEnd                = -1;
45ea844a1aSMatthew Knepley   (*s)->perm                = NULL;
46ea844a1aSMatthew Knepley   (*s)->pointMajor          = PETSC_TRUE;
4787e637c6Sksagiyam   (*s)->includesConstraints = PETSC_TRUE;
48ea844a1aSMatthew Knepley   (*s)->atlasDof            = NULL;
49ea844a1aSMatthew Knepley   (*s)->atlasOff            = NULL;
50ea844a1aSMatthew Knepley   (*s)->bc                  = NULL;
51ea844a1aSMatthew Knepley   (*s)->bcIndices           = NULL;
52ea844a1aSMatthew Knepley   (*s)->setup               = PETSC_FALSE;
53ea844a1aSMatthew Knepley   (*s)->numFields           = 0;
54ea844a1aSMatthew Knepley   (*s)->fieldNames          = NULL;
55ea844a1aSMatthew Knepley   (*s)->field               = NULL;
56ea844a1aSMatthew Knepley   (*s)->useFieldOff         = PETSC_FALSE;
57b778fa18SValeria Barra   (*s)->compNames           = NULL;
58ea844a1aSMatthew Knepley   (*s)->clObj               = NULL;
59c459fbc1SJed Brown   (*s)->clHash              = NULL;
60ea844a1aSMatthew Knepley   (*s)->clSection           = NULL;
61ea844a1aSMatthew Knepley   (*s)->clPoints            = NULL;
6269c11d05SVaclav Hapla   PetscCall(PetscSectionInvalidateMaxDof_Internal(*s));
63ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
64ea844a1aSMatthew Knepley }
65ea844a1aSMatthew Knepley 
66ea844a1aSMatthew Knepley /*@
67ea844a1aSMatthew Knepley   PetscSectionCopy - Creates a shallow (if possible) copy of the PetscSection
68ea844a1aSMatthew Knepley 
69ea844a1aSMatthew Knepley   Collective
70ea844a1aSMatthew Knepley 
71ea844a1aSMatthew Knepley   Input Parameter:
72ea844a1aSMatthew Knepley . section - the PetscSection
73ea844a1aSMatthew Knepley 
74ea844a1aSMatthew Knepley   Output Parameter:
75ea844a1aSMatthew Knepley . newSection - the copy
76ea844a1aSMatthew Knepley 
77ea844a1aSMatthew Knepley   Level: intermediate
78ea844a1aSMatthew Knepley 
79db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`, `PetscSectionDestroy()`
80ea844a1aSMatthew Knepley @*/
81*9371c9d4SSatish Balay PetscErrorCode PetscSectionCopy(PetscSection section, PetscSection newSection) {
82ea844a1aSMatthew Knepley   PetscSectionSym sym;
83ea844a1aSMatthew Knepley   IS              perm;
84b778fa18SValeria Barra   PetscInt        numFields, f, c, pStart, pEnd, p;
85ea844a1aSMatthew Knepley 
86ea844a1aSMatthew Knepley   PetscFunctionBegin;
87ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
88ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(newSection, PETSC_SECTION_CLASSID, 2);
899566063dSJacob Faibussowitsch   PetscCall(PetscSectionReset(newSection));
909566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(section, &numFields));
919566063dSJacob Faibussowitsch   if (numFields) PetscCall(PetscSectionSetNumFields(newSection, numFields));
92ea844a1aSMatthew Knepley   for (f = 0; f < numFields; ++f) {
93b778fa18SValeria Barra     const char *fieldName = NULL, *compName = NULL;
94ea844a1aSMatthew Knepley     PetscInt    numComp = 0;
95ea844a1aSMatthew Knepley 
969566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldName(section, f, &fieldName));
979566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldName(newSection, f, fieldName));
989566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(section, f, &numComp));
999566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldComponents(newSection, f, numComp));
100b778fa18SValeria Barra     for (c = 0; c < numComp; ++c) {
1019566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetComponentName(section, f, c, &compName));
1029566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetComponentName(newSection, f, c, compName));
103b778fa18SValeria Barra     }
1049566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldSym(section, f, &sym));
1059566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldSym(newSection, f, sym));
106ea844a1aSMatthew Knepley   }
1079566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(section, &pStart, &pEnd));
1089566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(newSection, pStart, pEnd));
1099566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetPermutation(section, &perm));
1109566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetPermutation(newSection, perm));
1119566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetSym(section, &sym));
1129566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetSym(newSection, sym));
113ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
114ea844a1aSMatthew Knepley     PetscInt dof, cdof, fcdof = 0;
115ea844a1aSMatthew Knepley 
1169566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(section, p, &dof));
1179566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(newSection, p, dof));
1189566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(section, p, &cdof));
1199566063dSJacob Faibussowitsch     if (cdof) PetscCall(PetscSectionSetConstraintDof(newSection, p, cdof));
120ea844a1aSMatthew Knepley     for (f = 0; f < numFields; ++f) {
1219566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(section, p, f, &dof));
1229566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldDof(newSection, p, f, dof));
123ea844a1aSMatthew Knepley       if (cdof) {
1249566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof));
1259566063dSJacob Faibussowitsch         if (fcdof) PetscCall(PetscSectionSetFieldConstraintDof(newSection, p, f, fcdof));
126ea844a1aSMatthew Knepley       }
127ea844a1aSMatthew Knepley     }
128ea844a1aSMatthew Knepley   }
1299566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(newSection));
130ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
131ea844a1aSMatthew Knepley     PetscInt        off, cdof, fcdof = 0;
132ea844a1aSMatthew Knepley     const PetscInt *cInd;
133ea844a1aSMatthew Knepley 
134ea844a1aSMatthew Knepley     /* Must set offsets in case they do not agree with the prefix sums */
1359566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(section, p, &off));
1369566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetOffset(newSection, p, off));
1379566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(section, p, &cdof));
138ea844a1aSMatthew Knepley     if (cdof) {
1399566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintIndices(section, p, &cInd));
1409566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetConstraintIndices(newSection, p, cInd));
141ea844a1aSMatthew Knepley       for (f = 0; f < numFields; ++f) {
1429566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof));
143ea844a1aSMatthew Knepley         if (fcdof) {
1449566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetFieldConstraintIndices(section, p, f, &cInd));
1459566063dSJacob Faibussowitsch           PetscCall(PetscSectionSetFieldConstraintIndices(newSection, p, f, cInd));
146ea844a1aSMatthew Knepley         }
147ea844a1aSMatthew Knepley       }
148ea844a1aSMatthew Knepley     }
149ea844a1aSMatthew Knepley   }
150ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
151ea844a1aSMatthew Knepley }
152ea844a1aSMatthew Knepley 
153ea844a1aSMatthew Knepley /*@
154ea844a1aSMatthew Knepley   PetscSectionClone - Creates a shallow (if possible) copy of the PetscSection
155ea844a1aSMatthew Knepley 
156ea844a1aSMatthew Knepley   Collective
157ea844a1aSMatthew Knepley 
158ea844a1aSMatthew Knepley   Input Parameter:
159ea844a1aSMatthew Knepley . section - the PetscSection
160ea844a1aSMatthew Knepley 
161ea844a1aSMatthew Knepley   Output Parameter:
162ea844a1aSMatthew Knepley . newSection - the copy
163ea844a1aSMatthew Knepley 
164ea844a1aSMatthew Knepley   Level: beginner
165ea844a1aSMatthew Knepley 
166db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`, `PetscSectionDestroy()`
167ea844a1aSMatthew Knepley @*/
168*9371c9d4SSatish Balay PetscErrorCode PetscSectionClone(PetscSection section, PetscSection *newSection) {
169ea844a1aSMatthew Knepley   PetscFunctionBegin;
170ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
171ea844a1aSMatthew Knepley   PetscValidPointer(newSection, 2);
1729566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)section), newSection));
1739566063dSJacob Faibussowitsch   PetscCall(PetscSectionCopy(section, *newSection));
174ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
175ea844a1aSMatthew Knepley }
176ea844a1aSMatthew Knepley 
177ea844a1aSMatthew Knepley /*@
178ea844a1aSMatthew Knepley   PetscSectionSetFromOptions - sets parameters in a PetscSection from the options database
179ea844a1aSMatthew Knepley 
18040750d41SVaclav Hapla   Collective
181ea844a1aSMatthew Knepley 
182ea844a1aSMatthew Knepley   Input Parameter:
183ea844a1aSMatthew Knepley . section - the PetscSection
184ea844a1aSMatthew Knepley 
185ea844a1aSMatthew Knepley   Options Database:
186147403d9SBarry Smith . -petscsection_point_major - PETSC_TRUE for point-major order
187ea844a1aSMatthew Knepley 
188ea844a1aSMatthew Knepley   Level: intermediate
189ea844a1aSMatthew Knepley 
190db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`, `PetscSectionDestroy()`
191ea844a1aSMatthew Knepley @*/
192*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFromOptions(PetscSection s) {
193ea844a1aSMatthew Knepley   PetscFunctionBegin;
194ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
195d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)s);
1969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscsection_point_major", "The for ordering, either point major or field major", "PetscSectionSetPointMajor", s->pointMajor, &s->pointMajor, NULL));
197ea844a1aSMatthew Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
198dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)s, PetscOptionsObject));
199d0609cedSBarry Smith   PetscOptionsEnd();
2009566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)s, NULL, "-petscsection_view"));
201ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
202ea844a1aSMatthew Knepley }
203ea844a1aSMatthew Knepley 
204ea844a1aSMatthew Knepley /*@
205ea844a1aSMatthew Knepley   PetscSectionCompare - Compares two sections
206ea844a1aSMatthew Knepley 
20740750d41SVaclav Hapla   Collective
208ea844a1aSMatthew Knepley 
2097a7aea1fSJed Brown   Input Parameters:
210ea844a1aSMatthew Knepley + s1 - the first PetscSection
211ea844a1aSMatthew Knepley - s2 - the second PetscSection
212ea844a1aSMatthew Knepley 
213ea844a1aSMatthew Knepley   Output Parameter:
214ea844a1aSMatthew Knepley . congruent - PETSC_TRUE if the two sections are congruent, PETSC_FALSE otherwise
215ea844a1aSMatthew Knepley 
216ea844a1aSMatthew Knepley   Level: intermediate
217ea844a1aSMatthew Knepley 
218ea844a1aSMatthew Knepley   Notes:
219ea844a1aSMatthew Knepley   Field names are disregarded.
220ea844a1aSMatthew Knepley 
221db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`, `PetscSectionCopy()`, `PetscSectionClone()`
222ea844a1aSMatthew Knepley @*/
223*9371c9d4SSatish Balay PetscErrorCode PetscSectionCompare(PetscSection s1, PetscSection s2, PetscBool *congruent) {
224ea844a1aSMatthew Knepley   PetscInt        pStart, pEnd, nfields, ncdof, nfcdof, p, f, n1, n2;
225ea844a1aSMatthew Knepley   const PetscInt *idx1, *idx2;
226ea844a1aSMatthew Knepley   IS              perm1, perm2;
227ea844a1aSMatthew Knepley   PetscBool       flg;
228ea844a1aSMatthew Knepley   PetscMPIInt     mflg;
229ea844a1aSMatthew Knepley 
230ea844a1aSMatthew Knepley   PetscFunctionBegin;
231ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s1, PETSC_SECTION_CLASSID, 1);
232ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s2, PETSC_SECTION_CLASSID, 2);
233064a246eSJacob Faibussowitsch   PetscValidBoolPointer(congruent, 3);
234ea844a1aSMatthew Knepley   flg = PETSC_FALSE;
235ea844a1aSMatthew Knepley 
2369566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)s1), PetscObjectComm((PetscObject)s2), &mflg));
237ea844a1aSMatthew Knepley   if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
238ea844a1aSMatthew Knepley     *congruent = PETSC_FALSE;
239ea844a1aSMatthew Knepley     PetscFunctionReturn(0);
240ea844a1aSMatthew Knepley   }
241ea844a1aSMatthew Knepley 
2429566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s1, &pStart, &pEnd));
2439566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s2, &n1, &n2));
244ea844a1aSMatthew Knepley   if (pStart != n1 || pEnd != n2) goto not_congruent;
245ea844a1aSMatthew Knepley 
2469566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetPermutation(s1, &perm1));
2479566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetPermutation(s2, &perm2));
248ea844a1aSMatthew Knepley   if (perm1 && perm2) {
2499566063dSJacob Faibussowitsch     PetscCall(ISEqual(perm1, perm2, congruent));
250ea844a1aSMatthew Knepley     if (!(*congruent)) goto not_congruent;
251ea844a1aSMatthew Knepley   } else if (perm1 != perm2) goto not_congruent;
252ea844a1aSMatthew Knepley 
253ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
2549566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(s1, p, &n1));
2559566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(s2, p, &n2));
256ea844a1aSMatthew Knepley     if (n1 != n2) goto not_congruent;
257ea844a1aSMatthew Knepley 
2589566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s1, p, &n1));
2599566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s2, p, &n2));
260ea844a1aSMatthew Knepley     if (n1 != n2) goto not_congruent;
261ea844a1aSMatthew Knepley 
2629566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s1, p, &ncdof));
2639566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s2, p, &n2));
264ea844a1aSMatthew Knepley     if (ncdof != n2) goto not_congruent;
265ea844a1aSMatthew Knepley 
2669566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintIndices(s1, p, &idx1));
2679566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintIndices(s2, p, &idx2));
2689566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(idx1, idx2, ncdof, congruent));
269ea844a1aSMatthew Knepley     if (!(*congruent)) goto not_congruent;
270ea844a1aSMatthew Knepley   }
271ea844a1aSMatthew Knepley 
2729566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s1, &nfields));
2739566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s2, &n2));
274ea844a1aSMatthew Knepley   if (nfields != n2) goto not_congruent;
275ea844a1aSMatthew Knepley 
276ea844a1aSMatthew Knepley   for (f = 0; f < nfields; ++f) {
2779566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s1, f, &n1));
2789566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s2, f, &n2));
279ea844a1aSMatthew Knepley     if (n1 != n2) goto not_congruent;
280ea844a1aSMatthew Knepley 
281ea844a1aSMatthew Knepley     for (p = pStart; p < pEnd; ++p) {
2829566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldOffset(s1, p, f, &n1));
2839566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldOffset(s2, p, f, &n2));
284ea844a1aSMatthew Knepley       if (n1 != n2) goto not_congruent;
285ea844a1aSMatthew Knepley 
2869566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s1, p, f, &n1));
2879566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s2, p, f, &n2));
288ea844a1aSMatthew Knepley       if (n1 != n2) goto not_congruent;
289ea844a1aSMatthew Knepley 
2909566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s1, p, f, &nfcdof));
2919566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s2, p, f, &n2));
292ea844a1aSMatthew Knepley       if (nfcdof != n2) goto not_congruent;
293ea844a1aSMatthew Knepley 
2949566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintIndices(s1, p, f, &idx1));
2959566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintIndices(s2, p, f, &idx2));
2969566063dSJacob Faibussowitsch       PetscCall(PetscArraycmp(idx1, idx2, nfcdof, congruent));
297ea844a1aSMatthew Knepley       if (!(*congruent)) goto not_congruent;
298ea844a1aSMatthew Knepley     }
299ea844a1aSMatthew Knepley   }
300ea844a1aSMatthew Knepley 
301ea844a1aSMatthew Knepley   flg = PETSC_TRUE;
302ea844a1aSMatthew Knepley not_congruent:
3031c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&flg, congruent, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)s1)));
304ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
305ea844a1aSMatthew Knepley }
306ea844a1aSMatthew Knepley 
307ea844a1aSMatthew Knepley /*@
308ea844a1aSMatthew Knepley   PetscSectionGetNumFields - Returns the number of fields, or 0 if no fields were defined.
309ea844a1aSMatthew Knepley 
31040750d41SVaclav Hapla   Not Collective
311ea844a1aSMatthew Knepley 
312ea844a1aSMatthew Knepley   Input Parameter:
313ea844a1aSMatthew Knepley . s - the PetscSection
314ea844a1aSMatthew Knepley 
315ea844a1aSMatthew Knepley   Output Parameter:
316ea844a1aSMatthew Knepley . numFields - the number of fields defined, or 0 if none were defined
317ea844a1aSMatthew Knepley 
318ea844a1aSMatthew Knepley   Level: intermediate
319ea844a1aSMatthew Knepley 
320db781477SPatrick Sanan .seealso: `PetscSectionSetNumFields()`
321ea844a1aSMatthew Knepley @*/
322*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetNumFields(PetscSection s, PetscInt *numFields) {
323ea844a1aSMatthew Knepley   PetscFunctionBegin;
324ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
325dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numFields, 2);
326ea844a1aSMatthew Knepley   *numFields = s->numFields;
327ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
328ea844a1aSMatthew Knepley }
329ea844a1aSMatthew Knepley 
330ea844a1aSMatthew Knepley /*@
331ea844a1aSMatthew Knepley   PetscSectionSetNumFields - Sets the number of fields.
332ea844a1aSMatthew Knepley 
33340750d41SVaclav Hapla   Not Collective
334ea844a1aSMatthew Knepley 
335ea844a1aSMatthew Knepley   Input Parameters:
336ea844a1aSMatthew Knepley + s - the PetscSection
337ea844a1aSMatthew Knepley - numFields - the number of fields
338ea844a1aSMatthew Knepley 
339ea844a1aSMatthew Knepley   Level: intermediate
340ea844a1aSMatthew Knepley 
341db781477SPatrick Sanan .seealso: `PetscSectionGetNumFields()`
342ea844a1aSMatthew Knepley @*/
343*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetNumFields(PetscSection s, PetscInt numFields) {
344ea844a1aSMatthew Knepley   PetscInt f;
345ea844a1aSMatthew Knepley 
346ea844a1aSMatthew Knepley   PetscFunctionBegin;
347ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
34808401ef6SPierre Jolivet   PetscCheck(numFields > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "The number of fields %" PetscInt_FMT " must be positive", numFields);
3499566063dSJacob Faibussowitsch   PetscCall(PetscSectionReset(s));
350ea844a1aSMatthew Knepley 
351ea844a1aSMatthew Knepley   s->numFields = numFields;
3529566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s->numFields, &s->numFieldComponents));
3539566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s->numFields, &s->fieldNames));
3549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s->numFields, &s->compNames));
3559566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(s->numFields, &s->field));
356ea844a1aSMatthew Knepley   for (f = 0; f < s->numFields; ++f) {
357ea844a1aSMatthew Knepley     char name[64];
358ea844a1aSMatthew Knepley 
359ea844a1aSMatthew Knepley     s->numFieldComponents[f] = 1;
360ea844a1aSMatthew Knepley 
3619566063dSJacob Faibussowitsch     PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), &s->field[f]));
3629566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(name, 64, "Field_%" PetscInt_FMT, f));
3639566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&s->fieldNames[f]));
3649566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(name, 64, "Component_0"));
3659566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(s->numFieldComponents[f], &s->compNames[f]));
3669566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&s->compNames[f][0]));
367ea844a1aSMatthew Knepley   }
368ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
369ea844a1aSMatthew Knepley }
370ea844a1aSMatthew Knepley 
371ea844a1aSMatthew Knepley /*@C
372ea844a1aSMatthew Knepley   PetscSectionGetFieldName - Returns the name of a field in the PetscSection
373ea844a1aSMatthew Knepley 
374ea844a1aSMatthew Knepley   Not Collective
375ea844a1aSMatthew Knepley 
376ea844a1aSMatthew Knepley   Input Parameters:
377ea844a1aSMatthew Knepley + s     - the PetscSection
378ea844a1aSMatthew Knepley - field - the field number
379ea844a1aSMatthew Knepley 
380ea844a1aSMatthew Knepley   Output Parameter:
381ea844a1aSMatthew Knepley . fieldName - the field name
382ea844a1aSMatthew Knepley 
383ea844a1aSMatthew Knepley   Level: intermediate
384ea844a1aSMatthew Knepley 
385db781477SPatrick Sanan .seealso: `PetscSectionSetFieldName()`
386ea844a1aSMatthew Knepley @*/
387*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldName(PetscSection s, PetscInt field, const char *fieldName[]) {
388ea844a1aSMatthew Knepley   PetscFunctionBegin;
389ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
390ea844a1aSMatthew Knepley   PetscValidPointer(fieldName, 3);
3912abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
392ea844a1aSMatthew Knepley   *fieldName = s->fieldNames[field];
393ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
394ea844a1aSMatthew Knepley }
395ea844a1aSMatthew Knepley 
396ea844a1aSMatthew Knepley /*@C
397ea844a1aSMatthew Knepley   PetscSectionSetFieldName - Sets the name of a field in the PetscSection
398ea844a1aSMatthew Knepley 
399ea844a1aSMatthew Knepley   Not Collective
400ea844a1aSMatthew Knepley 
401ea844a1aSMatthew Knepley   Input Parameters:
402ea844a1aSMatthew Knepley + s     - the PetscSection
403ea844a1aSMatthew Knepley . field - the field number
404ea844a1aSMatthew Knepley - fieldName - the field name
405ea844a1aSMatthew Knepley 
406ea844a1aSMatthew Knepley   Level: intermediate
407ea844a1aSMatthew Knepley 
408db781477SPatrick Sanan .seealso: `PetscSectionGetFieldName()`
409ea844a1aSMatthew Knepley @*/
410*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldName(PetscSection s, PetscInt field, const char fieldName[]) {
411ea844a1aSMatthew Knepley   PetscFunctionBegin;
412ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
413ea844a1aSMatthew Knepley   if (fieldName) PetscValidCharPointer(fieldName, 3);
4142abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
4159566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->fieldNames[field]));
4169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(fieldName, (char **)&s->fieldNames[field]));
417ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
418ea844a1aSMatthew Knepley }
419ea844a1aSMatthew Knepley 
420b778fa18SValeria Barra /*@C
421b778fa18SValeria Barra   PetscSectionGetComponentName - Gets the name of a field component in the PetscSection
422b778fa18SValeria Barra 
423b778fa18SValeria Barra   Not Collective
424b778fa18SValeria Barra 
425b778fa18SValeria Barra   Input Parameters:
426b778fa18SValeria Barra + s     - the PetscSection
427b778fa18SValeria Barra . field - the field number
428b778fa18SValeria Barra . comp  - the component number
429b778fa18SValeria Barra - compName - the component name
430b778fa18SValeria Barra 
431b778fa18SValeria Barra   Level: intermediate
432b778fa18SValeria Barra 
433db781477SPatrick Sanan .seealso: `PetscSectionSetComponentName()`
434b778fa18SValeria Barra @*/
435*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetComponentName(PetscSection s, PetscInt field, PetscInt comp, const char *compName[]) {
436b778fa18SValeria Barra   PetscFunctionBegin;
437b778fa18SValeria Barra   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
438064a246eSJacob Faibussowitsch   PetscValidPointer(compName, 4);
4392abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
4402abc8c78SJacob Faibussowitsch   PetscSectionCheckValidFieldComponent(comp, s->numFieldComponents[field]);
441b778fa18SValeria Barra   *compName = s->compNames[field][comp];
442b778fa18SValeria Barra   PetscFunctionReturn(0);
443b778fa18SValeria Barra }
444b778fa18SValeria Barra 
445b778fa18SValeria Barra /*@C
446b778fa18SValeria Barra   PetscSectionSetComponentName - Sets the name of a field component in the PetscSection
447b778fa18SValeria Barra 
448b778fa18SValeria Barra   Not Collective
449b778fa18SValeria Barra 
450b778fa18SValeria Barra   Input Parameters:
451b778fa18SValeria Barra + s     - the PetscSection
452b778fa18SValeria Barra . field - the field number
453b778fa18SValeria Barra . comp  - the component number
454b778fa18SValeria Barra - compName - the component name
455b778fa18SValeria Barra 
456b778fa18SValeria Barra   Level: intermediate
457b778fa18SValeria Barra 
458db781477SPatrick Sanan .seealso: `PetscSectionGetComponentName()`
459b778fa18SValeria Barra @*/
460*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetComponentName(PetscSection s, PetscInt field, PetscInt comp, const char compName[]) {
461b778fa18SValeria Barra   PetscFunctionBegin;
462b778fa18SValeria Barra   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
463064a246eSJacob Faibussowitsch   if (compName) PetscValidCharPointer(compName, 4);
4642abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
4652abc8c78SJacob Faibussowitsch   PetscSectionCheckValidFieldComponent(comp, s->numFieldComponents[field]);
4669566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->compNames[field][comp]));
4679566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(compName, (char **)&s->compNames[field][comp]));
468b778fa18SValeria Barra   PetscFunctionReturn(0);
469b778fa18SValeria Barra }
470b778fa18SValeria Barra 
471ea844a1aSMatthew Knepley /*@
472ea844a1aSMatthew Knepley   PetscSectionGetFieldComponents - Returns the number of field components for the given field.
473ea844a1aSMatthew Knepley 
47440750d41SVaclav Hapla   Not Collective
475ea844a1aSMatthew Knepley 
476ea844a1aSMatthew Knepley   Input Parameters:
477ea844a1aSMatthew Knepley + s - the PetscSection
478ea844a1aSMatthew Knepley - field - the field number
479ea844a1aSMatthew Knepley 
480ea844a1aSMatthew Knepley   Output Parameter:
481ea844a1aSMatthew Knepley . numComp - the number of field components
482ea844a1aSMatthew Knepley 
483ea844a1aSMatthew Knepley   Level: intermediate
484ea844a1aSMatthew Knepley 
485db781477SPatrick Sanan .seealso: `PetscSectionSetFieldComponents()`, `PetscSectionGetNumFields()`
486ea844a1aSMatthew Knepley @*/
487*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldComponents(PetscSection s, PetscInt field, PetscInt *numComp) {
488ea844a1aSMatthew Knepley   PetscFunctionBegin;
489ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
4902abc8c78SJacob Faibussowitsch   PetscValidIntPointer(numComp, 3);
4912abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
492ea844a1aSMatthew Knepley   *numComp = s->numFieldComponents[field];
493ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
494ea844a1aSMatthew Knepley }
495ea844a1aSMatthew Knepley 
496ea844a1aSMatthew Knepley /*@
497ea844a1aSMatthew Knepley   PetscSectionSetFieldComponents - Sets the number of field components for the given field.
498ea844a1aSMatthew Knepley 
49940750d41SVaclav Hapla   Not Collective
500ea844a1aSMatthew Knepley 
501ea844a1aSMatthew Knepley   Input Parameters:
502ea844a1aSMatthew Knepley + s - the PetscSection
503ea844a1aSMatthew Knepley . field - the field number
504ea844a1aSMatthew Knepley - numComp - the number of field components
505ea844a1aSMatthew Knepley 
506ea844a1aSMatthew Knepley   Level: intermediate
507ea844a1aSMatthew Knepley 
508db781477SPatrick Sanan .seealso: `PetscSectionGetFieldComponents()`, `PetscSectionGetNumFields()`
509ea844a1aSMatthew Knepley @*/
510*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldComponents(PetscSection s, PetscInt field, PetscInt numComp) {
511b778fa18SValeria Barra   PetscInt c;
512b778fa18SValeria Barra 
513ea844a1aSMatthew Knepley   PetscFunctionBegin;
514ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
5152abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
516b778fa18SValeria Barra   if (s->compNames) {
517*9371c9d4SSatish Balay     for (c = 0; c < s->numFieldComponents[field]; ++c) { PetscCall(PetscFree(s->compNames[field][c])); }
5189566063dSJacob Faibussowitsch     PetscCall(PetscFree(s->compNames[field]));
519b778fa18SValeria Barra   }
520b778fa18SValeria Barra 
521ea844a1aSMatthew Knepley   s->numFieldComponents[field] = numComp;
522b778fa18SValeria Barra   if (numComp) {
5239566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numComp, (char ***)&s->compNames[field]));
524b778fa18SValeria Barra     for (c = 0; c < numComp; ++c) {
5252abc8c78SJacob Faibussowitsch       char name[64];
5262abc8c78SJacob Faibussowitsch 
5279566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(name, 64, "%" PetscInt_FMT, c));
5289566063dSJacob Faibussowitsch       PetscCall(PetscStrallocpy(name, (char **)&s->compNames[field][c]));
529b778fa18SValeria Barra     }
530b778fa18SValeria Barra   }
531ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
532ea844a1aSMatthew Knepley }
533ea844a1aSMatthew Knepley 
534ea844a1aSMatthew Knepley /*@
535ea844a1aSMatthew Knepley   PetscSectionGetChart - Returns the range [pStart, pEnd) in which points lie.
536ea844a1aSMatthew Knepley 
53740750d41SVaclav Hapla   Not Collective
538ea844a1aSMatthew Knepley 
539ea844a1aSMatthew Knepley   Input Parameter:
540ea844a1aSMatthew Knepley . s - the PetscSection
541ea844a1aSMatthew Knepley 
542ea844a1aSMatthew Knepley   Output Parameters:
543ea844a1aSMatthew Knepley + pStart - the first point
544ea844a1aSMatthew Knepley - pEnd - one past the last point
545ea844a1aSMatthew Knepley 
546ea844a1aSMatthew Knepley   Level: intermediate
547ea844a1aSMatthew Knepley 
548db781477SPatrick Sanan .seealso: `PetscSectionSetChart()`, `PetscSectionCreate()`
549ea844a1aSMatthew Knepley @*/
550*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetChart(PetscSection s, PetscInt *pStart, PetscInt *pEnd) {
551ea844a1aSMatthew Knepley   PetscFunctionBegin;
552ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
553ea844a1aSMatthew Knepley   if (pStart) *pStart = s->pStart;
554ea844a1aSMatthew Knepley   if (pEnd) *pEnd = s->pEnd;
555ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
556ea844a1aSMatthew Knepley }
557ea844a1aSMatthew Knepley 
558ea844a1aSMatthew Knepley /*@
559ea844a1aSMatthew Knepley   PetscSectionSetChart - Sets the range [pStart, pEnd) in which points lie.
560ea844a1aSMatthew Knepley 
56140750d41SVaclav Hapla   Not Collective
562ea844a1aSMatthew Knepley 
563ea844a1aSMatthew Knepley   Input Parameters:
564ea844a1aSMatthew Knepley + s - the PetscSection
565ea844a1aSMatthew Knepley . pStart - the first point
566ea844a1aSMatthew Knepley - pEnd - one past the last point
567ea844a1aSMatthew Knepley 
568ea844a1aSMatthew Knepley   Level: intermediate
569ea844a1aSMatthew Knepley 
570db781477SPatrick Sanan .seealso: `PetscSectionGetChart()`, `PetscSectionCreate()`
571ea844a1aSMatthew Knepley @*/
572*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetChart(PetscSection s, PetscInt pStart, PetscInt pEnd) {
573ea844a1aSMatthew Knepley   PetscInt f;
574ea844a1aSMatthew Knepley 
575ea844a1aSMatthew Knepley   PetscFunctionBegin;
576ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
5779318fe57SMatthew G. Knepley   if (pStart == s->pStart && pEnd == s->pEnd) PetscFunctionReturn(0);
578ea844a1aSMatthew Knepley   /* Cannot Reset() because it destroys field information */
579ea844a1aSMatthew Knepley   s->setup = PETSC_FALSE;
5809566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&s->bc));
5819566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->bcIndices));
5829566063dSJacob Faibussowitsch   PetscCall(PetscFree2(s->atlasDof, s->atlasOff));
583ea844a1aSMatthew Knepley 
584ea844a1aSMatthew Knepley   s->pStart = pStart;
585ea844a1aSMatthew Knepley   s->pEnd   = pEnd;
5869566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2((pEnd - pStart), &s->atlasDof, (pEnd - pStart), &s->atlasOff));
5879566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(s->atlasDof, pEnd - pStart));
588*9371c9d4SSatish Balay   for (f = 0; f < s->numFields; ++f) { PetscCall(PetscSectionSetChart(s->field[f], pStart, pEnd)); }
589ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
590ea844a1aSMatthew Knepley }
591ea844a1aSMatthew Knepley 
592ea844a1aSMatthew Knepley /*@
593ea844a1aSMatthew Knepley   PetscSectionGetPermutation - Returns the permutation of [0, pEnd-pStart) or NULL
594ea844a1aSMatthew Knepley 
59540750d41SVaclav Hapla   Not Collective
596ea844a1aSMatthew Knepley 
597ea844a1aSMatthew Knepley   Input Parameter:
598ea844a1aSMatthew Knepley . s - the PetscSection
599ea844a1aSMatthew Knepley 
600ea844a1aSMatthew Knepley   Output Parameters:
601ea844a1aSMatthew Knepley . perm - The permutation as an IS
602ea844a1aSMatthew Knepley 
603ea844a1aSMatthew Knepley   Level: intermediate
604ea844a1aSMatthew Knepley 
605db781477SPatrick Sanan .seealso: `PetscSectionSetPermutation()`, `PetscSectionCreate()`
606ea844a1aSMatthew Knepley @*/
607*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetPermutation(PetscSection s, IS *perm) {
608ea844a1aSMatthew Knepley   PetscFunctionBegin;
609ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
610*9371c9d4SSatish Balay   if (perm) {
611*9371c9d4SSatish Balay     PetscValidPointer(perm, 2);
612*9371c9d4SSatish Balay     *perm = s->perm;
613*9371c9d4SSatish Balay   }
614ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
615ea844a1aSMatthew Knepley }
616ea844a1aSMatthew Knepley 
617ea844a1aSMatthew Knepley /*@
618ea844a1aSMatthew Knepley   PetscSectionSetPermutation - Sets the permutation for [0, pEnd-pStart)
619ea844a1aSMatthew Knepley 
62040750d41SVaclav Hapla   Not Collective
621ea844a1aSMatthew Knepley 
622ea844a1aSMatthew Knepley   Input Parameters:
623ea844a1aSMatthew Knepley + s - the PetscSection
624ea844a1aSMatthew Knepley - perm - the permutation of points
625ea844a1aSMatthew Knepley 
626ea844a1aSMatthew Knepley   Level: intermediate
627ea844a1aSMatthew Knepley 
628db781477SPatrick Sanan .seealso: `PetscSectionGetPermutation()`, `PetscSectionCreate()`
629ea844a1aSMatthew Knepley @*/
630*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetPermutation(PetscSection s, IS perm) {
631ea844a1aSMatthew Knepley   PetscFunctionBegin;
632ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
633ea844a1aSMatthew Knepley   if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 2);
63428b400f6SJacob Faibussowitsch   PetscCheck(!s->setup, PetscObjectComm((PetscObject)s), PETSC_ERR_ARG_WRONGSTATE, "Cannot set a permutation after the section is setup");
635ea844a1aSMatthew Knepley   if (s->perm != perm) {
6369566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&s->perm));
637ea844a1aSMatthew Knepley     if (perm) {
638ea844a1aSMatthew Knepley       s->perm = perm;
6399566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)s->perm));
640ea844a1aSMatthew Knepley     }
641ea844a1aSMatthew Knepley   }
642ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
643ea844a1aSMatthew Knepley }
644ea844a1aSMatthew Knepley 
645ea844a1aSMatthew Knepley /*@
646ea844a1aSMatthew Knepley   PetscSectionGetPointMajor - Returns the flag for dof ordering, true if it is point major, otherwise field major
647ea844a1aSMatthew Knepley 
64840750d41SVaclav Hapla   Not Collective
649ea844a1aSMatthew Knepley 
650ea844a1aSMatthew Knepley   Input Parameter:
651ea844a1aSMatthew Knepley . s - the PetscSection
652ea844a1aSMatthew Knepley 
653ea844a1aSMatthew Knepley   Output Parameter:
654ea844a1aSMatthew Knepley . pm - the flag for point major ordering
655ea844a1aSMatthew Knepley 
656ea844a1aSMatthew Knepley   Level: intermediate
657ea844a1aSMatthew Knepley 
658db781477SPatrick Sanan .seealso: `PetscSectionSetPointMajor()`
659ea844a1aSMatthew Knepley @*/
660*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetPointMajor(PetscSection s, PetscBool *pm) {
661ea844a1aSMatthew Knepley   PetscFunctionBegin;
662ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
663dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(pm, 2);
664ea844a1aSMatthew Knepley   *pm = s->pointMajor;
665ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
666ea844a1aSMatthew Knepley }
667ea844a1aSMatthew Knepley 
668ea844a1aSMatthew Knepley /*@
669ea844a1aSMatthew Knepley   PetscSectionSetPointMajor - Sets the flag for dof ordering, true if it is point major, otherwise field major
670ea844a1aSMatthew Knepley 
67140750d41SVaclav Hapla   Not Collective
672ea844a1aSMatthew Knepley 
673ea844a1aSMatthew Knepley   Input Parameters:
674ea844a1aSMatthew Knepley + s  - the PetscSection
675ea844a1aSMatthew Knepley - pm - the flag for point major ordering
676ea844a1aSMatthew Knepley 
677ea844a1aSMatthew Knepley   Level: intermediate
678ea844a1aSMatthew Knepley 
679db781477SPatrick Sanan .seealso: `PetscSectionGetPointMajor()`
680ea844a1aSMatthew Knepley @*/
681*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetPointMajor(PetscSection s, PetscBool pm) {
682ea844a1aSMatthew Knepley   PetscFunctionBegin;
683ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
68428b400f6SJacob Faibussowitsch   PetscCheck(!s->setup, PetscObjectComm((PetscObject)s), PETSC_ERR_ARG_WRONGSTATE, "Cannot set the dof ordering after the section is setup");
685ea844a1aSMatthew Knepley   s->pointMajor = pm;
686ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
687ea844a1aSMatthew Knepley }
688ea844a1aSMatthew Knepley 
689ea844a1aSMatthew Knepley /*@
69087e637c6Sksagiyam   PetscSectionGetIncludesConstraints - Returns the flag indicating if constrained dofs were included when computing offsets
69187e637c6Sksagiyam 
69240750d41SVaclav Hapla   Not Collective
69387e637c6Sksagiyam 
69487e637c6Sksagiyam   Input Parameter:
69587e637c6Sksagiyam . s - the PetscSection
69687e637c6Sksagiyam 
69787e637c6Sksagiyam   Output Parameter:
69887e637c6Sksagiyam . includesConstraints - the flag indicating if constrained dofs were included when computing offsets
69987e637c6Sksagiyam 
70087e637c6Sksagiyam   Level: intermediate
70187e637c6Sksagiyam 
702db781477SPatrick Sanan .seealso: `PetscSectionSetIncludesConstraints()`
70387e637c6Sksagiyam @*/
704*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetIncludesConstraints(PetscSection s, PetscBool *includesConstraints) {
70587e637c6Sksagiyam   PetscFunctionBegin;
70687e637c6Sksagiyam   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
70787e637c6Sksagiyam   PetscValidBoolPointer(includesConstraints, 2);
70887e637c6Sksagiyam   *includesConstraints = s->includesConstraints;
70987e637c6Sksagiyam   PetscFunctionReturn(0);
71087e637c6Sksagiyam }
71187e637c6Sksagiyam 
71287e637c6Sksagiyam /*@
71387e637c6Sksagiyam   PetscSectionSetIncludesConstraints - Sets the flag indicating if constrained dofs are to be included when computing offsets
71487e637c6Sksagiyam 
71540750d41SVaclav Hapla   Not Collective
71687e637c6Sksagiyam 
71787e637c6Sksagiyam   Input Parameters:
71887e637c6Sksagiyam + s  - the PetscSection
71987e637c6Sksagiyam - includesConstraints - the flag indicating if constrained dofs are to be included when computing offsets
72087e637c6Sksagiyam 
72187e637c6Sksagiyam   Level: intermediate
72287e637c6Sksagiyam 
723db781477SPatrick Sanan .seealso: `PetscSectionGetIncludesConstraints()`
72487e637c6Sksagiyam @*/
725*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetIncludesConstraints(PetscSection s, PetscBool includesConstraints) {
72687e637c6Sksagiyam   PetscFunctionBegin;
72787e637c6Sksagiyam   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
72828b400f6SJacob Faibussowitsch   PetscCheck(!s->setup, PetscObjectComm((PetscObject)s), PETSC_ERR_ARG_WRONGSTATE, "Cannot set includesConstraints after the section is set up");
72987e637c6Sksagiyam   s->includesConstraints = includesConstraints;
73087e637c6Sksagiyam   PetscFunctionReturn(0);
73187e637c6Sksagiyam }
73287e637c6Sksagiyam 
73387e637c6Sksagiyam /*@
734ea844a1aSMatthew Knepley   PetscSectionGetDof - Return the number of degrees of freedom associated with a given point.
735ea844a1aSMatthew Knepley 
73640750d41SVaclav Hapla   Not Collective
737ea844a1aSMatthew Knepley 
738ea844a1aSMatthew Knepley   Input Parameters:
739ea844a1aSMatthew Knepley + s - the PetscSection
740ea844a1aSMatthew Knepley - point - the point
741ea844a1aSMatthew Knepley 
742ea844a1aSMatthew Knepley   Output Parameter:
743ea844a1aSMatthew Knepley . numDof - the number of dof
744ea844a1aSMatthew Knepley 
745ea844a1aSMatthew Knepley   Level: intermediate
746ea844a1aSMatthew Knepley 
747db781477SPatrick Sanan .seealso: `PetscSectionSetDof()`, `PetscSectionCreate()`
748ea844a1aSMatthew Knepley @*/
749*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetDof(PetscSection s, PetscInt point, PetscInt *numDof) {
75076bd3646SJed Brown   PetscFunctionBeginHot;
751ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
752dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numDof, 3);
753c8bf3acbSVaclav Hapla   PetscAssert(point >= s->pStart && point < s->pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, s->pStart, s->pEnd);
754ea844a1aSMatthew Knepley   *numDof = s->atlasDof[point - s->pStart];
755ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
756ea844a1aSMatthew Knepley }
757ea844a1aSMatthew Knepley 
758ea844a1aSMatthew Knepley /*@
759ea844a1aSMatthew Knepley   PetscSectionSetDof - Sets the number of degrees of freedom associated with a given point.
760ea844a1aSMatthew Knepley 
76140750d41SVaclav Hapla   Not Collective
762ea844a1aSMatthew Knepley 
763ea844a1aSMatthew Knepley   Input Parameters:
764ea844a1aSMatthew Knepley + s - the PetscSection
765ea844a1aSMatthew Knepley . point - the point
766ea844a1aSMatthew Knepley - numDof - the number of dof
767ea844a1aSMatthew Knepley 
768ea844a1aSMatthew Knepley   Level: intermediate
769ea844a1aSMatthew Knepley 
770db781477SPatrick Sanan .seealso: `PetscSectionGetDof()`, `PetscSectionAddDof()`, `PetscSectionCreate()`
771ea844a1aSMatthew Knepley @*/
772*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetDof(PetscSection s, PetscInt point, PetscInt numDof) {
773ea844a1aSMatthew Knepley   PetscFunctionBegin;
774ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
775c8bf3acbSVaclav Hapla   PetscAssert(point >= s->pStart && point < s->pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, s->pStart, s->pEnd);
776ea844a1aSMatthew Knepley   s->atlasDof[point - s->pStart] = numDof;
77769c11d05SVaclav Hapla   PetscCall(PetscSectionInvalidateMaxDof_Internal(s));
778ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
779ea844a1aSMatthew Knepley }
780ea844a1aSMatthew Knepley 
781ea844a1aSMatthew Knepley /*@
782ea844a1aSMatthew Knepley   PetscSectionAddDof - Adds to the number of degrees of freedom associated with a given point.
783ea844a1aSMatthew Knepley 
78440750d41SVaclav Hapla   Not Collective
785ea844a1aSMatthew Knepley 
786ea844a1aSMatthew Knepley   Input Parameters:
787ea844a1aSMatthew Knepley + s - the PetscSection
788ea844a1aSMatthew Knepley . point - the point
789ea844a1aSMatthew Knepley - numDof - the number of additional dof
790ea844a1aSMatthew Knepley 
791ea844a1aSMatthew Knepley   Level: intermediate
792ea844a1aSMatthew Knepley 
793db781477SPatrick Sanan .seealso: `PetscSectionGetDof()`, `PetscSectionSetDof()`, `PetscSectionCreate()`
794ea844a1aSMatthew Knepley @*/
795*9371c9d4SSatish Balay PetscErrorCode PetscSectionAddDof(PetscSection s, PetscInt point, PetscInt numDof) {
79676bd3646SJed Brown   PetscFunctionBeginHot;
797ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
798c8bf3acbSVaclav Hapla   PetscAssert(point >= s->pStart && point < s->pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, s->pStart, s->pEnd);
799ea844a1aSMatthew Knepley   s->atlasDof[point - s->pStart] += numDof;
80069c11d05SVaclav Hapla   PetscCall(PetscSectionInvalidateMaxDof_Internal(s));
801ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
802ea844a1aSMatthew Knepley }
803ea844a1aSMatthew Knepley 
804ea844a1aSMatthew Knepley /*@
805ea844a1aSMatthew Knepley   PetscSectionGetFieldDof - Return the number of degrees of freedom associated with a field on a given point.
806ea844a1aSMatthew Knepley 
80740750d41SVaclav Hapla   Not Collective
808ea844a1aSMatthew Knepley 
809ea844a1aSMatthew Knepley   Input Parameters:
810ea844a1aSMatthew Knepley + s - the PetscSection
811ea844a1aSMatthew Knepley . point - the point
812ea844a1aSMatthew Knepley - field - the field
813ea844a1aSMatthew Knepley 
814ea844a1aSMatthew Knepley   Output Parameter:
815ea844a1aSMatthew Knepley . numDof - the number of dof
816ea844a1aSMatthew Knepley 
817ea844a1aSMatthew Knepley   Level: intermediate
818ea844a1aSMatthew Knepley 
819db781477SPatrick Sanan .seealso: `PetscSectionSetFieldDof()`, `PetscSectionCreate()`
820ea844a1aSMatthew Knepley @*/
821*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt *numDof) {
822ea844a1aSMatthew Knepley   PetscFunctionBegin;
823ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
8242abc8c78SJacob Faibussowitsch   PetscValidIntPointer(numDof, 4);
8252abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
8269566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetDof(s->field[field], point, numDof));
827ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
828ea844a1aSMatthew Knepley }
829ea844a1aSMatthew Knepley 
830ea844a1aSMatthew Knepley /*@
831ea844a1aSMatthew Knepley   PetscSectionSetFieldDof - Sets the number of degrees of freedom associated with a field on a given point.
832ea844a1aSMatthew Knepley 
83340750d41SVaclav Hapla   Not Collective
834ea844a1aSMatthew Knepley 
835ea844a1aSMatthew Knepley   Input Parameters:
836ea844a1aSMatthew Knepley + s - the PetscSection
837ea844a1aSMatthew Knepley . point - the point
838ea844a1aSMatthew Knepley . field - the field
839ea844a1aSMatthew Knepley - numDof - the number of dof
840ea844a1aSMatthew Knepley 
841ea844a1aSMatthew Knepley   Level: intermediate
842ea844a1aSMatthew Knepley 
843db781477SPatrick Sanan .seealso: `PetscSectionGetFieldDof()`, `PetscSectionCreate()`
844ea844a1aSMatthew Knepley @*/
845*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) {
846ea844a1aSMatthew Knepley   PetscFunctionBegin;
847ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
8482abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
8499566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetDof(s->field[field], point, numDof));
850ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
851ea844a1aSMatthew Knepley }
852ea844a1aSMatthew Knepley 
853ea844a1aSMatthew Knepley /*@
854ea844a1aSMatthew Knepley   PetscSectionAddFieldDof - Adds a number of degrees of freedom associated with a field on a given point.
855ea844a1aSMatthew Knepley 
85640750d41SVaclav Hapla   Not Collective
857ea844a1aSMatthew Knepley 
858ea844a1aSMatthew Knepley   Input Parameters:
859ea844a1aSMatthew Knepley + s - the PetscSection
860ea844a1aSMatthew Knepley . point - the point
861ea844a1aSMatthew Knepley . field - the field
862ea844a1aSMatthew Knepley - numDof - the number of dof
863ea844a1aSMatthew Knepley 
864ea844a1aSMatthew Knepley   Level: intermediate
865ea844a1aSMatthew Knepley 
866db781477SPatrick Sanan .seealso: `PetscSectionSetFieldDof()`, `PetscSectionGetFieldDof()`, `PetscSectionCreate()`
867ea844a1aSMatthew Knepley @*/
868*9371c9d4SSatish Balay PetscErrorCode PetscSectionAddFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) {
869ea844a1aSMatthew Knepley   PetscFunctionBegin;
870ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
8712abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
8729566063dSJacob Faibussowitsch   PetscCall(PetscSectionAddDof(s->field[field], point, numDof));
873ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
874ea844a1aSMatthew Knepley }
875ea844a1aSMatthew Knepley 
876ea844a1aSMatthew Knepley /*@
877ea844a1aSMatthew Knepley   PetscSectionGetConstraintDof - Return the number of constrained degrees of freedom associated with a given point.
878ea844a1aSMatthew Knepley 
87940750d41SVaclav Hapla   Not Collective
880ea844a1aSMatthew Knepley 
881ea844a1aSMatthew Knepley   Input Parameters:
882ea844a1aSMatthew Knepley + s - the PetscSection
883ea844a1aSMatthew Knepley - point - the point
884ea844a1aSMatthew Knepley 
885ea844a1aSMatthew Knepley   Output Parameter:
886ea844a1aSMatthew Knepley . numDof - the number of dof which are fixed by constraints
887ea844a1aSMatthew Knepley 
888ea844a1aSMatthew Knepley   Level: intermediate
889ea844a1aSMatthew Knepley 
890db781477SPatrick Sanan .seealso: `PetscSectionGetDof()`, `PetscSectionSetConstraintDof()`, `PetscSectionCreate()`
891ea844a1aSMatthew Knepley @*/
892*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetConstraintDof(PetscSection s, PetscInt point, PetscInt *numDof) {
893ea844a1aSMatthew Knepley   PetscFunctionBegin;
894ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
895dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numDof, 3);
896ea844a1aSMatthew Knepley   if (s->bc) {
8979566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s->bc, point, numDof));
898ea844a1aSMatthew Knepley   } else *numDof = 0;
899ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
900ea844a1aSMatthew Knepley }
901ea844a1aSMatthew Knepley 
902ea844a1aSMatthew Knepley /*@
903ea844a1aSMatthew Knepley   PetscSectionSetConstraintDof - Set the number of constrained degrees of freedom associated with a given point.
904ea844a1aSMatthew Knepley 
90540750d41SVaclav Hapla   Not Collective
906ea844a1aSMatthew Knepley 
907ea844a1aSMatthew Knepley   Input Parameters:
908ea844a1aSMatthew Knepley + s - the PetscSection
909ea844a1aSMatthew Knepley . point - the point
910ea844a1aSMatthew Knepley - numDof - the number of dof which are fixed by constraints
911ea844a1aSMatthew Knepley 
912ea844a1aSMatthew Knepley   Level: intermediate
913ea844a1aSMatthew Knepley 
914db781477SPatrick Sanan .seealso: `PetscSectionSetDof()`, `PetscSectionGetConstraintDof()`, `PetscSectionCreate()`
915ea844a1aSMatthew Knepley @*/
916*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetConstraintDof(PetscSection s, PetscInt point, PetscInt numDof) {
917ea844a1aSMatthew Knepley   PetscFunctionBegin;
918ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
919ea844a1aSMatthew Knepley   if (numDof) {
9207c0883d5SVaclav Hapla     PetscCall(PetscSectionCheckConstraints_Private(s));
9219566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(s->bc, point, numDof));
922ea844a1aSMatthew Knepley   }
923ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
924ea844a1aSMatthew Knepley }
925ea844a1aSMatthew Knepley 
926ea844a1aSMatthew Knepley /*@
927ea844a1aSMatthew Knepley   PetscSectionAddConstraintDof - Increment the number of constrained degrees of freedom associated with a given point.
928ea844a1aSMatthew Knepley 
92940750d41SVaclav Hapla   Not Collective
930ea844a1aSMatthew Knepley 
931ea844a1aSMatthew Knepley   Input Parameters:
932ea844a1aSMatthew Knepley + s - the PetscSection
933ea844a1aSMatthew Knepley . point - the point
934ea844a1aSMatthew Knepley - numDof - the number of additional dof which are fixed by constraints
935ea844a1aSMatthew Knepley 
936ea844a1aSMatthew Knepley   Level: intermediate
937ea844a1aSMatthew Knepley 
938db781477SPatrick Sanan .seealso: `PetscSectionAddDof()`, `PetscSectionGetConstraintDof()`, `PetscSectionCreate()`
939ea844a1aSMatthew Knepley @*/
940*9371c9d4SSatish Balay PetscErrorCode PetscSectionAddConstraintDof(PetscSection s, PetscInt point, PetscInt numDof) {
941ea844a1aSMatthew Knepley   PetscFunctionBegin;
942ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
943ea844a1aSMatthew Knepley   if (numDof) {
9447c0883d5SVaclav Hapla     PetscCall(PetscSectionCheckConstraints_Private(s));
9459566063dSJacob Faibussowitsch     PetscCall(PetscSectionAddDof(s->bc, point, numDof));
946ea844a1aSMatthew Knepley   }
947ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
948ea844a1aSMatthew Knepley }
949ea844a1aSMatthew Knepley 
950ea844a1aSMatthew Knepley /*@
951ea844a1aSMatthew Knepley   PetscSectionGetFieldConstraintDof - Return the number of constrained degrees of freedom associated with a given field on a point.
952ea844a1aSMatthew Knepley 
95340750d41SVaclav Hapla   Not Collective
954ea844a1aSMatthew Knepley 
955ea844a1aSMatthew Knepley   Input Parameters:
956ea844a1aSMatthew Knepley + s - the PetscSection
957ea844a1aSMatthew Knepley . point - the point
958ea844a1aSMatthew Knepley - field - the field
959ea844a1aSMatthew Knepley 
960ea844a1aSMatthew Knepley   Output Parameter:
961ea844a1aSMatthew Knepley . numDof - the number of dof which are fixed by constraints
962ea844a1aSMatthew Knepley 
963ea844a1aSMatthew Knepley   Level: intermediate
964ea844a1aSMatthew Knepley 
965db781477SPatrick Sanan .seealso: `PetscSectionGetDof()`, `PetscSectionSetFieldConstraintDof()`, `PetscSectionCreate()`
966ea844a1aSMatthew Knepley @*/
967*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt *numDof) {
968ea844a1aSMatthew Knepley   PetscFunctionBegin;
969ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
9702abc8c78SJacob Faibussowitsch   PetscValidIntPointer(numDof, 4);
9712abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
9729566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetConstraintDof(s->field[field], point, numDof));
973ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
974ea844a1aSMatthew Knepley }
975ea844a1aSMatthew Knepley 
976ea844a1aSMatthew Knepley /*@
977ea844a1aSMatthew Knepley   PetscSectionSetFieldConstraintDof - Set the number of constrained degrees of freedom associated with a given field on a point.
978ea844a1aSMatthew Knepley 
97940750d41SVaclav Hapla   Not Collective
980ea844a1aSMatthew Knepley 
981ea844a1aSMatthew Knepley   Input Parameters:
982ea844a1aSMatthew Knepley + s - the PetscSection
983ea844a1aSMatthew Knepley . point - the point
984ea844a1aSMatthew Knepley . field - the field
985ea844a1aSMatthew Knepley - numDof - the number of dof which are fixed by constraints
986ea844a1aSMatthew Knepley 
987ea844a1aSMatthew Knepley   Level: intermediate
988ea844a1aSMatthew Knepley 
989db781477SPatrick Sanan .seealso: `PetscSectionSetDof()`, `PetscSectionGetFieldConstraintDof()`, `PetscSectionCreate()`
990ea844a1aSMatthew Knepley @*/
991*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) {
992ea844a1aSMatthew Knepley   PetscFunctionBegin;
993ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
9942abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
9959566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetConstraintDof(s->field[field], point, numDof));
996ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
997ea844a1aSMatthew Knepley }
998ea844a1aSMatthew Knepley 
999ea844a1aSMatthew Knepley /*@
1000ea844a1aSMatthew Knepley   PetscSectionAddFieldConstraintDof - Increment the number of constrained degrees of freedom associated with a given field on a point.
1001ea844a1aSMatthew Knepley 
100240750d41SVaclav Hapla   Not Collective
1003ea844a1aSMatthew Knepley 
1004ea844a1aSMatthew Knepley   Input Parameters:
1005ea844a1aSMatthew Knepley + s - the PetscSection
1006ea844a1aSMatthew Knepley . point - the point
1007ea844a1aSMatthew Knepley . field - the field
1008ea844a1aSMatthew Knepley - numDof - the number of additional dof which are fixed by constraints
1009ea844a1aSMatthew Knepley 
1010ea844a1aSMatthew Knepley   Level: intermediate
1011ea844a1aSMatthew Knepley 
1012db781477SPatrick Sanan .seealso: `PetscSectionAddDof()`, `PetscSectionGetFieldConstraintDof()`, `PetscSectionCreate()`
1013ea844a1aSMatthew Knepley @*/
1014*9371c9d4SSatish Balay PetscErrorCode PetscSectionAddFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) {
1015ea844a1aSMatthew Knepley   PetscFunctionBegin;
1016ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
10172abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
10189566063dSJacob Faibussowitsch   PetscCall(PetscSectionAddConstraintDof(s->field[field], point, numDof));
1019ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1020ea844a1aSMatthew Knepley }
1021ea844a1aSMatthew Knepley 
1022ea844a1aSMatthew Knepley /*@
1023ea844a1aSMatthew Knepley   PetscSectionSetUpBC - Setup the subsections describing boundary conditions.
1024ea844a1aSMatthew Knepley 
102540750d41SVaclav Hapla   Not Collective
1026ea844a1aSMatthew Knepley 
1027ea844a1aSMatthew Knepley   Input Parameter:
1028ea844a1aSMatthew Knepley . s - the PetscSection
1029ea844a1aSMatthew Knepley 
1030ea844a1aSMatthew Knepley   Level: advanced
1031ea844a1aSMatthew Knepley 
1032db781477SPatrick Sanan .seealso: `PetscSectionSetUp()`, `PetscSectionCreate()`
1033ea844a1aSMatthew Knepley @*/
1034*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetUpBC(PetscSection s) {
1035ea844a1aSMatthew Knepley   PetscFunctionBegin;
1036ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1037ea844a1aSMatthew Knepley   if (s->bc) {
1038ea844a1aSMatthew Knepley     const PetscInt last = (s->bc->pEnd - s->bc->pStart) - 1;
1039ea844a1aSMatthew Knepley 
10409566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetUp(s->bc));
10418da24d32SBarry Smith     PetscCall(PetscMalloc1((last >= 0 ? s->bc->atlasOff[last] + s->bc->atlasDof[last] : 0), &s->bcIndices));
1042ea844a1aSMatthew Knepley   }
1043ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1044ea844a1aSMatthew Knepley }
1045ea844a1aSMatthew Knepley 
1046ea844a1aSMatthew Knepley /*@
1047ea844a1aSMatthew Knepley   PetscSectionSetUp - Calculate offsets based upon the number of degrees of freedom for each point.
1048ea844a1aSMatthew Knepley 
104940750d41SVaclav Hapla   Not Collective
1050ea844a1aSMatthew Knepley 
1051ea844a1aSMatthew Knepley   Input Parameter:
1052ea844a1aSMatthew Knepley . s - the PetscSection
1053ea844a1aSMatthew Knepley 
1054ea844a1aSMatthew Knepley   Level: intermediate
1055ea844a1aSMatthew Knepley 
1056db781477SPatrick Sanan .seealso: `PetscSectionCreate()`
1057ea844a1aSMatthew Knepley @*/
1058*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetUp(PetscSection s) {
1059ea844a1aSMatthew Knepley   const PetscInt *pind   = NULL;
1060ea844a1aSMatthew Knepley   PetscInt        offset = 0, foff, p, f;
1061ea844a1aSMatthew Knepley 
1062ea844a1aSMatthew Knepley   PetscFunctionBegin;
1063ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1064ea844a1aSMatthew Knepley   if (s->setup) PetscFunctionReturn(0);
1065ea844a1aSMatthew Knepley   s->setup = PETSC_TRUE;
1066ea844a1aSMatthew Knepley   /* Set offsets and field offsets for all points */
1067ea844a1aSMatthew Knepley   /*   Assume that all fields have the same chart */
106828b400f6SJacob Faibussowitsch   PetscCheck(s->includesConstraints, PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscSectionSetUp is currently unsupported for includesConstraints = PETSC_TRUE");
10699566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISGetIndices(s->perm, &pind));
1070ea844a1aSMatthew Knepley   if (s->pointMajor) {
1071ea844a1aSMatthew Knepley     for (p = 0; p < s->pEnd - s->pStart; ++p) {
1072ea844a1aSMatthew Knepley       const PetscInt q = pind ? pind[p] : p;
1073ea844a1aSMatthew Knepley 
1074ea844a1aSMatthew Knepley       /* Set point offset */
1075ea844a1aSMatthew Knepley       s->atlasOff[q] = offset;
1076ea844a1aSMatthew Knepley       offset += s->atlasDof[q];
1077ea844a1aSMatthew Knepley       /* Set field offset */
1078ea844a1aSMatthew Knepley       for (f = 0, foff = s->atlasOff[q]; f < s->numFields; ++f) {
1079ea844a1aSMatthew Knepley         PetscSection sf = s->field[f];
1080ea844a1aSMatthew Knepley 
1081ea844a1aSMatthew Knepley         sf->atlasOff[q] = foff;
1082ea844a1aSMatthew Knepley         foff += sf->atlasDof[q];
1083ea844a1aSMatthew Knepley       }
1084ea844a1aSMatthew Knepley     }
1085ea844a1aSMatthew Knepley   } else {
1086ea844a1aSMatthew Knepley     /* Set field offsets for all points */
1087ea844a1aSMatthew Knepley     for (f = 0; f < s->numFields; ++f) {
1088ea844a1aSMatthew Knepley       PetscSection sf = s->field[f];
1089ea844a1aSMatthew Knepley 
1090ea844a1aSMatthew Knepley       for (p = 0; p < s->pEnd - s->pStart; ++p) {
1091ea844a1aSMatthew Knepley         const PetscInt q = pind ? pind[p] : p;
1092ea844a1aSMatthew Knepley 
1093ea844a1aSMatthew Knepley         sf->atlasOff[q] = offset;
1094ea844a1aSMatthew Knepley         offset += sf->atlasDof[q];
1095ea844a1aSMatthew Knepley       }
1096ea844a1aSMatthew Knepley     }
1097ea844a1aSMatthew Knepley     /* Disable point offsets since these are unused */
1098*9371c9d4SSatish Balay     for (p = 0; p < s->pEnd - s->pStart; ++p) { s->atlasOff[p] = -1; }
1099ea844a1aSMatthew Knepley   }
11009566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISRestoreIndices(s->perm, &pind));
1101ea844a1aSMatthew Knepley   /* Setup BC sections */
11029566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUpBC(s));
11039566063dSJacob Faibussowitsch   for (f = 0; f < s->numFields; ++f) PetscCall(PetscSectionSetUpBC(s->field[f]));
1104ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1105ea844a1aSMatthew Knepley }
1106ea844a1aSMatthew Knepley 
1107ea844a1aSMatthew Knepley /*@
1108ea844a1aSMatthew Knepley   PetscSectionGetMaxDof - Return the maximum number of degrees of freedom on any point in the chart
1109ea844a1aSMatthew Knepley 
111040750d41SVaclav Hapla   Not Collective
1111ea844a1aSMatthew Knepley 
1112ea844a1aSMatthew Knepley   Input Parameters:
1113ea844a1aSMatthew Knepley . s - the PetscSection
1114ea844a1aSMatthew Knepley 
1115ea844a1aSMatthew Knepley   Output Parameter:
1116ea844a1aSMatthew Knepley . maxDof - the maximum dof
1117ea844a1aSMatthew Knepley 
1118ea844a1aSMatthew Knepley   Level: intermediate
1119ea844a1aSMatthew Knepley 
112069c11d05SVaclav Hapla   Notes:
112169c11d05SVaclav Hapla   The returned number is up-to-date without need for PetscSectionSetUp().
112269c11d05SVaclav Hapla 
112369c11d05SVaclav Hapla   Developer Notes:
112469c11d05SVaclav Hapla   The returned number is calculated lazily and stashed.
112569c11d05SVaclav Hapla   A call to PetscSectionInvalidateMaxDof_Internal() invalidates the stashed value.
112669c11d05SVaclav Hapla   PetscSectionInvalidateMaxDof_Internal() is called in PetscSectionSetDof(), PetscSectionAddDof() and PetscSectionReset().
112769c11d05SVaclav Hapla   It should also be called every time atlasDof is modified directly.
112869c11d05SVaclav Hapla 
1129db781477SPatrick Sanan .seealso: `PetscSectionGetDof()`, `PetscSectionSetDof()`, `PetscSectionAddDof()`, `PetscSectionCreate()`
1130ea844a1aSMatthew Knepley @*/
1131*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetMaxDof(PetscSection s, PetscInt *maxDof) {
113269c11d05SVaclav Hapla   PetscInt p;
113369c11d05SVaclav Hapla 
1134ea844a1aSMatthew Knepley   PetscFunctionBegin;
1135ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1136dadcf809SJacob Faibussowitsch   PetscValidIntPointer(maxDof, 2);
113769c11d05SVaclav Hapla   if (s->maxDof == PETSC_MIN_INT) {
113869c11d05SVaclav Hapla     s->maxDof = 0;
1139*9371c9d4SSatish Balay     for (p = 0; p < s->pEnd - s->pStart; ++p) { s->maxDof = PetscMax(s->maxDof, s->atlasDof[p]); }
114069c11d05SVaclav Hapla   }
1141ea844a1aSMatthew Knepley   *maxDof = s->maxDof;
1142ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1143ea844a1aSMatthew Knepley }
1144ea844a1aSMatthew Knepley 
1145ea844a1aSMatthew Knepley /*@
1146ea844a1aSMatthew Knepley   PetscSectionGetStorageSize - Return the size of an array or local Vec capable of holding all the degrees of freedom.
1147ea844a1aSMatthew Knepley 
114840750d41SVaclav Hapla   Not Collective
1149ea844a1aSMatthew Knepley 
1150ea844a1aSMatthew Knepley   Input Parameter:
1151ea844a1aSMatthew Knepley . s - the PetscSection
1152ea844a1aSMatthew Knepley 
1153ea844a1aSMatthew Knepley   Output Parameter:
1154ea844a1aSMatthew Knepley . size - the size of an array which can hold all the dofs
1155ea844a1aSMatthew Knepley 
1156ea844a1aSMatthew Knepley   Level: intermediate
1157ea844a1aSMatthew Knepley 
1158db781477SPatrick Sanan .seealso: `PetscSectionGetOffset()`, `PetscSectionGetConstrainedStorageSize()`, `PetscSectionCreate()`
1159ea844a1aSMatthew Knepley @*/
1160*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetStorageSize(PetscSection s, PetscInt *size) {
1161ea844a1aSMatthew Knepley   PetscInt p, n = 0;
1162ea844a1aSMatthew Knepley 
1163ea844a1aSMatthew Knepley   PetscFunctionBegin;
1164ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1165dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 2);
1166ea844a1aSMatthew Knepley   for (p = 0; p < s->pEnd - s->pStart; ++p) n += s->atlasDof[p] > 0 ? s->atlasDof[p] : 0;
1167ea844a1aSMatthew Knepley   *size = n;
1168ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1169ea844a1aSMatthew Knepley }
1170ea844a1aSMatthew Knepley 
1171ea844a1aSMatthew Knepley /*@
1172ea844a1aSMatthew Knepley   PetscSectionGetConstrainedStorageSize - Return the size of an array or local Vec capable of holding all unconstrained degrees of freedom.
1173ea844a1aSMatthew Knepley 
117440750d41SVaclav Hapla   Not Collective
1175ea844a1aSMatthew Knepley 
1176064ec1f3Sprj-   Input Parameter:
1177064ec1f3Sprj- . s - the PetscSection
1178ea844a1aSMatthew Knepley 
1179ea844a1aSMatthew Knepley   Output Parameter:
1180ea844a1aSMatthew Knepley . size - the size of an array which can hold all unconstrained dofs
1181ea844a1aSMatthew Knepley 
1182ea844a1aSMatthew Knepley   Level: intermediate
1183ea844a1aSMatthew Knepley 
1184db781477SPatrick Sanan .seealso: `PetscSectionGetStorageSize()`, `PetscSectionGetOffset()`, `PetscSectionCreate()`
1185ea844a1aSMatthew Knepley @*/
1186*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetConstrainedStorageSize(PetscSection s, PetscInt *size) {
1187ea844a1aSMatthew Knepley   PetscInt p, n = 0;
1188ea844a1aSMatthew Knepley 
1189ea844a1aSMatthew Knepley   PetscFunctionBegin;
1190ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1191dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 2);
1192ea844a1aSMatthew Knepley   for (p = 0; p < s->pEnd - s->pStart; ++p) {
1193ea844a1aSMatthew Knepley     const PetscInt cdof = s->bc ? s->bc->atlasDof[p] : 0;
1194ea844a1aSMatthew Knepley     n += s->atlasDof[p] > 0 ? s->atlasDof[p] - cdof : 0;
1195ea844a1aSMatthew Knepley   }
1196ea844a1aSMatthew Knepley   *size = n;
1197ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1198ea844a1aSMatthew Knepley }
1199ea844a1aSMatthew Knepley 
1200ea844a1aSMatthew Knepley /*@
1201ea844a1aSMatthew Knepley   PetscSectionCreateGlobalSection - Create a section describing the global field layout using
1202ea844a1aSMatthew Knepley   the local section and an SF describing the section point overlap.
1203ea844a1aSMatthew Knepley 
1204ea844a1aSMatthew Knepley   Input Parameters:
1205ea844a1aSMatthew Knepley + s - The PetscSection for the local field layout
1206ea844a1aSMatthew Knepley . sf - The SF describing parallel layout of the section points (leaves are unowned local points)
1207ea844a1aSMatthew Knepley . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs
1208ea844a1aSMatthew Knepley - localOffsets - If PETSC_TRUE, use local rather than global offsets for the points
1209ea844a1aSMatthew Knepley 
1210ea844a1aSMatthew Knepley   Output Parameter:
1211ea844a1aSMatthew Knepley . gsection - The PetscSection for the global field layout
1212ea844a1aSMatthew Knepley 
1213ea844a1aSMatthew Knepley   Note: This gives negative sizes and offsets to points not owned by this process
1214ea844a1aSMatthew Knepley 
1215ea844a1aSMatthew Knepley   Level: intermediate
1216ea844a1aSMatthew Knepley 
1217db781477SPatrick Sanan .seealso: `PetscSectionCreate()`
1218ea844a1aSMatthew Knepley @*/
1219*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateGlobalSection(PetscSection s, PetscSF sf, PetscBool includeConstraints, PetscBool localOffsets, PetscSection *gsection) {
1220ea844a1aSMatthew Knepley   PetscSection    gs;
1221ea844a1aSMatthew Knepley   const PetscInt *pind = NULL;
1222ea844a1aSMatthew Knepley   PetscInt       *recv = NULL, *neg = NULL;
1223046d2115Sksagiyam   PetscInt        pStart, pEnd, p, dof, cdof, off, foff, globalOff = 0, nroots, nlocal, maxleaf;
1224046d2115Sksagiyam   PetscInt        numFields, f, numComponents;
1225ea844a1aSMatthew Knepley 
1226ea844a1aSMatthew Knepley   PetscFunctionBegin;
1227ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1228ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
1229ea844a1aSMatthew Knepley   PetscValidLogicalCollectiveBool(s, includeConstraints, 3);
1230ea844a1aSMatthew Knepley   PetscValidLogicalCollectiveBool(s, localOffsets, 4);
1231ea844a1aSMatthew Knepley   PetscValidPointer(gsection, 5);
123228b400f6SJacob Faibussowitsch   PetscCheck(s->pointMajor, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for field major ordering");
12339566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), &gs));
12349566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s, &numFields));
12359566063dSJacob Faibussowitsch   if (numFields > 0) PetscCall(PetscSectionSetNumFields(gs, numFields));
12369566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
12379566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(gs, pStart, pEnd));
123887e637c6Sksagiyam   gs->includesConstraints = includeConstraints;
12399566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL));
1240ea844a1aSMatthew Knepley   nlocal = nroots; /* The local/leaf space matches global/root space */
1241ea844a1aSMatthew Knepley   /* Must allocate for all points visible to SF, which may be more than this section */
1242ea844a1aSMatthew Knepley   if (nroots >= 0) { /* nroots < 0 means that the graph has not been set, only happens in serial */
12439566063dSJacob Faibussowitsch     PetscCall(PetscSFGetLeafRange(sf, NULL, &maxleaf));
124408401ef6SPierre Jolivet     PetscCheck(nroots >= pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "SF roots %" PetscInt_FMT " < pEnd %" PetscInt_FMT, nroots, pEnd);
124508401ef6SPierre Jolivet     PetscCheck(maxleaf < nroots, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Max local leaf %" PetscInt_FMT " >= nroots %" PetscInt_FMT, maxleaf, nroots);
12469566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nroots, &neg, nlocal, &recv));
12479566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(neg, nroots));
1248ea844a1aSMatthew Knepley   }
1249ea844a1aSMatthew Knepley   /* Mark all local points with negative dof */
1250ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
12519566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
12529566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(gs, p, dof));
12539566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
12549566063dSJacob Faibussowitsch     if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(gs, p, cdof));
1255ea844a1aSMatthew Knepley     if (neg) neg[p] = -(dof + 1);
1256ea844a1aSMatthew Knepley   }
12579566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUpBC(gs));
12589566063dSJacob Faibussowitsch   if (gs->bcIndices) PetscCall(PetscArraycpy(gs->bcIndices, s->bcIndices, gs->bc->atlasOff[gs->bc->pEnd - gs->bc->pStart - 1] + gs->bc->atlasDof[gs->bc->pEnd - gs->bc->pStart - 1]));
1259ea844a1aSMatthew Knepley   if (nroots >= 0) {
12609566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(recv, nlocal));
12619566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, recv, MPI_REPLACE));
12629566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, recv, MPI_REPLACE));
1263ea844a1aSMatthew Knepley     for (p = pStart; p < pEnd; ++p) {
1264ea844a1aSMatthew Knepley       if (recv[p] < 0) {
1265ea844a1aSMatthew Knepley         gs->atlasDof[p - pStart] = recv[p];
12669566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetDof(s, p, &dof));
126708401ef6SPierre Jolivet         PetscCheck(-(recv[p] + 1) == dof, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Global dof %" PetscInt_FMT " for point %" PetscInt_FMT " is not the unconstrained %" PetscInt_FMT, -(recv[p] + 1), p, dof);
1268ea844a1aSMatthew Knepley       }
1269ea844a1aSMatthew Knepley     }
1270ea844a1aSMatthew Knepley   }
1271ea844a1aSMatthew Knepley   /* Calculate new sizes, get process offset, and calculate point offsets */
12729566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISGetIndices(s->perm, &pind));
1273ea844a1aSMatthew Knepley   for (p = 0, off = 0; p < pEnd - pStart; ++p) {
1274ea844a1aSMatthew Knepley     const PetscInt q = pind ? pind[p] : p;
1275ea844a1aSMatthew Knepley 
1276ea844a1aSMatthew Knepley     cdof            = (!includeConstraints && s->bc) ? s->bc->atlasDof[q] : 0;
1277ea844a1aSMatthew Knepley     gs->atlasOff[q] = off;
1278ea844a1aSMatthew Knepley     off += gs->atlasDof[q] > 0 ? gs->atlasDof[q] - cdof : 0;
1279ea844a1aSMatthew Knepley   }
1280ea844a1aSMatthew Knepley   if (!localOffsets) {
12819566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s)));
1282ea844a1aSMatthew Knepley     globalOff -= off;
1283ea844a1aSMatthew Knepley   }
1284ea844a1aSMatthew Knepley   for (p = pStart, off = 0; p < pEnd; ++p) {
1285ea844a1aSMatthew Knepley     gs->atlasOff[p - pStart] += globalOff;
1286ea844a1aSMatthew Knepley     if (neg) neg[p] = -(gs->atlasOff[p - pStart] + 1);
1287ea844a1aSMatthew Knepley   }
12889566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISRestoreIndices(s->perm, &pind));
1289ea844a1aSMatthew Knepley   /* Put in negative offsets for ghost points */
1290ea844a1aSMatthew Knepley   if (nroots >= 0) {
12919566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(recv, nlocal));
12929566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, recv, MPI_REPLACE));
12939566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, recv, MPI_REPLACE));
1294ea844a1aSMatthew Knepley     for (p = pStart; p < pEnd; ++p) {
1295ea844a1aSMatthew Knepley       if (recv[p] < 0) gs->atlasOff[p - pStart] = recv[p];
1296ea844a1aSMatthew Knepley     }
1297ea844a1aSMatthew Knepley   }
12989566063dSJacob Faibussowitsch   PetscCall(PetscFree2(neg, recv));
1299046d2115Sksagiyam   /* Set field dofs/offsets/constraints */
1300046d2115Sksagiyam   for (f = 0; f < numFields; ++f) {
1301046d2115Sksagiyam     gs->field[f]->includesConstraints = includeConstraints;
13029566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s, f, &numComponents));
13039566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldComponents(gs, f, numComponents));
1304046d2115Sksagiyam   }
1305046d2115Sksagiyam   for (p = pStart; p < pEnd; ++p) {
13069566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(gs, p, &off));
1307046d2115Sksagiyam     for (f = 0, foff = off; f < numFields; ++f) {
13089566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &cdof));
13099566063dSJacob Faibussowitsch       if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetFieldConstraintDof(gs, p, f, cdof));
13109566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s, p, f, &dof));
13119566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldDof(gs, p, f, off < 0 ? -(dof + 1) : dof));
13129566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldOffset(gs, p, f, foff));
13139566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(gs, p, f, &cdof));
1314046d2115Sksagiyam       foff = off < 0 ? foff - (dof - cdof) : foff + (dof - cdof);
1315046d2115Sksagiyam     }
1316046d2115Sksagiyam   }
1317046d2115Sksagiyam   for (f = 0; f < numFields; ++f) {
1318046d2115Sksagiyam     PetscSection gfs = gs->field[f];
1319046d2115Sksagiyam 
13209566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetUpBC(gfs));
13219566063dSJacob Faibussowitsch     if (gfs->bcIndices) PetscCall(PetscArraycpy(gfs->bcIndices, s->field[f]->bcIndices, gfs->bc->atlasOff[gfs->bc->pEnd - gfs->bc->pStart - 1] + gfs->bc->atlasDof[gfs->bc->pEnd - gfs->bc->pStart - 1]));
1322046d2115Sksagiyam   }
1323046d2115Sksagiyam   gs->setup = PETSC_TRUE;
13249566063dSJacob Faibussowitsch   PetscCall(PetscSectionViewFromOptions(gs, NULL, "-global_section_view"));
1325ea844a1aSMatthew Knepley   *gsection = gs;
1326ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1327ea844a1aSMatthew Knepley }
1328ea844a1aSMatthew Knepley 
1329ea844a1aSMatthew Knepley /*@
1330ea844a1aSMatthew Knepley   PetscSectionCreateGlobalSectionCensored - Create a section describing the global field layout using
1331ea844a1aSMatthew Knepley   the local section and an SF describing the section point overlap.
1332ea844a1aSMatthew Knepley 
1333ea844a1aSMatthew Knepley   Input Parameters:
1334ea844a1aSMatthew Knepley + s - The PetscSection for the local field layout
1335ea844a1aSMatthew Knepley . sf - The SF describing parallel layout of the section points
1336ea844a1aSMatthew Knepley . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs
1337ea844a1aSMatthew Knepley . numExcludes - The number of exclusion ranges
1338ea844a1aSMatthew Knepley - excludes - An array [start_0, end_0, start_1, end_1, ...] where there are numExcludes pairs
1339ea844a1aSMatthew Knepley 
1340ea844a1aSMatthew Knepley   Output Parameter:
1341ea844a1aSMatthew Knepley . gsection - The PetscSection for the global field layout
1342ea844a1aSMatthew Knepley 
1343ea844a1aSMatthew Knepley   Note: This gives negative sizes and offsets to points not owned by this process
1344ea844a1aSMatthew Knepley 
1345ea844a1aSMatthew Knepley   Level: advanced
1346ea844a1aSMatthew Knepley 
1347db781477SPatrick Sanan .seealso: `PetscSectionCreate()`
1348ea844a1aSMatthew Knepley @*/
1349*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateGlobalSectionCensored(PetscSection s, PetscSF sf, PetscBool includeConstraints, PetscInt numExcludes, const PetscInt excludes[], PetscSection *gsection) {
1350ea844a1aSMatthew Knepley   const PetscInt *pind = NULL;
1351ea844a1aSMatthew Knepley   PetscInt       *neg = NULL, *tmpOff = NULL;
1352ea844a1aSMatthew Knepley   PetscInt        pStart, pEnd, p, e, dof, cdof, off, globalOff = 0, nroots;
1353ea844a1aSMatthew Knepley 
1354ea844a1aSMatthew Knepley   PetscFunctionBegin;
1355ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1356ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
1357ea844a1aSMatthew Knepley   PetscValidPointer(gsection, 6);
13589566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection));
13599566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
13609566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd));
13619566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL));
1362ea844a1aSMatthew Knepley   if (nroots >= 0) {
136308401ef6SPierre Jolivet     PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart);
13649566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(nroots, &neg));
1365ea844a1aSMatthew Knepley     if (nroots > pEnd - pStart) {
13669566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(nroots, &tmpOff));
1367ea844a1aSMatthew Knepley     } else {
1368ea844a1aSMatthew Knepley       tmpOff = &(*gsection)->atlasDof[-pStart];
1369ea844a1aSMatthew Knepley     }
1370ea844a1aSMatthew Knepley   }
1371ea844a1aSMatthew Knepley   /* Mark ghost points with negative dof */
1372ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1373ea844a1aSMatthew Knepley     for (e = 0; e < numExcludes; ++e) {
1374ea844a1aSMatthew Knepley       if ((p >= excludes[e * 2 + 0]) && (p < excludes[e * 2 + 1])) {
13759566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetDof(*gsection, p, 0));
1376ea844a1aSMatthew Knepley         break;
1377ea844a1aSMatthew Knepley       }
1378ea844a1aSMatthew Knepley     }
1379ea844a1aSMatthew Knepley     if (e < numExcludes) continue;
13809566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
13819566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(*gsection, p, dof));
13829566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
13839566063dSJacob Faibussowitsch     if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof));
1384ea844a1aSMatthew Knepley     if (neg) neg[p] = -(dof + 1);
1385ea844a1aSMatthew Knepley   }
13869566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUpBC(*gsection));
1387ea844a1aSMatthew Knepley   if (nroots >= 0) {
13889566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
13899566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
1390ea844a1aSMatthew Knepley     if (nroots > pEnd - pStart) {
1391*9371c9d4SSatish Balay       for (p = pStart; p < pEnd; ++p) {
1392*9371c9d4SSatish Balay         if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p];
1393*9371c9d4SSatish Balay       }
1394ea844a1aSMatthew Knepley     }
1395ea844a1aSMatthew Knepley   }
1396ea844a1aSMatthew Knepley   /* Calculate new sizes, get proccess offset, and calculate point offsets */
13979566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISGetIndices(s->perm, &pind));
1398ea844a1aSMatthew Knepley   for (p = 0, off = 0; p < pEnd - pStart; ++p) {
1399ea844a1aSMatthew Knepley     const PetscInt q = pind ? pind[p] : p;
1400ea844a1aSMatthew Knepley 
1401ea844a1aSMatthew Knepley     cdof                     = (!includeConstraints && s->bc) ? s->bc->atlasDof[q] : 0;
1402ea844a1aSMatthew Knepley     (*gsection)->atlasOff[q] = off;
1403ea844a1aSMatthew Knepley     off += (*gsection)->atlasDof[q] > 0 ? (*gsection)->atlasDof[q] - cdof : 0;
1404ea844a1aSMatthew Knepley   }
14059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s)));
1406ea844a1aSMatthew Knepley   globalOff -= off;
1407ea844a1aSMatthew Knepley   for (p = 0, off = 0; p < pEnd - pStart; ++p) {
1408ea844a1aSMatthew Knepley     (*gsection)->atlasOff[p] += globalOff;
1409ea844a1aSMatthew Knepley     if (neg) neg[p + pStart] = -((*gsection)->atlasOff[p] + 1);
1410ea844a1aSMatthew Knepley   }
14119566063dSJacob Faibussowitsch   if (s->perm) PetscCall(ISRestoreIndices(s->perm, &pind));
1412ea844a1aSMatthew Knepley   /* Put in negative offsets for ghost points */
1413ea844a1aSMatthew Knepley   if (nroots >= 0) {
1414ea844a1aSMatthew Knepley     if (nroots == pEnd - pStart) tmpOff = &(*gsection)->atlasOff[-pStart];
14159566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
14169566063dSJacob Faibussowitsch     PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
1417ea844a1aSMatthew Knepley     if (nroots > pEnd - pStart) {
1418*9371c9d4SSatish Balay       for (p = pStart; p < pEnd; ++p) {
1419*9371c9d4SSatish Balay         if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p];
1420*9371c9d4SSatish Balay       }
1421ea844a1aSMatthew Knepley     }
1422ea844a1aSMatthew Knepley   }
14239566063dSJacob Faibussowitsch   if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff));
14249566063dSJacob Faibussowitsch   PetscCall(PetscFree(neg));
1425ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1426ea844a1aSMatthew Knepley }
1427ea844a1aSMatthew Knepley 
1428ea844a1aSMatthew Knepley /*@
1429ea844a1aSMatthew Knepley   PetscSectionGetPointLayout - Get the PetscLayout associated with the section points
1430ea844a1aSMatthew Knepley 
1431ea844a1aSMatthew Knepley   Collective on comm
1432ea844a1aSMatthew Knepley 
1433ea844a1aSMatthew Knepley   Input Parameters:
1434ea844a1aSMatthew Knepley + comm - The MPI_Comm
1435ea844a1aSMatthew Knepley - s    - The PetscSection
1436ea844a1aSMatthew Knepley 
1437ea844a1aSMatthew Knepley   Output Parameter:
1438ea844a1aSMatthew Knepley . layout - The point layout for the section
1439ea844a1aSMatthew Knepley 
14401681d8a4SMatthew Knepley   Note: This is usually called for the default global section.
1441ea844a1aSMatthew Knepley 
1442ea844a1aSMatthew Knepley   Level: advanced
1443ea844a1aSMatthew Knepley 
1444db781477SPatrick Sanan .seealso: `PetscSectionGetValueLayout()`, `PetscSectionCreate()`
1445ea844a1aSMatthew Knepley @*/
1446*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetPointLayout(MPI_Comm comm, PetscSection s, PetscLayout *layout) {
1447ea844a1aSMatthew Knepley   PetscInt pStart, pEnd, p, localSize = 0;
1448ea844a1aSMatthew Knepley 
1449ea844a1aSMatthew Knepley   PetscFunctionBegin;
14509566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
1451ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1452ea844a1aSMatthew Knepley     PetscInt dof;
1453ea844a1aSMatthew Knepley 
14549566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
14559120ba30SVaclav Hapla     if (dof >= 0) ++localSize;
1456ea844a1aSMatthew Knepley   }
14579566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, layout));
14589566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetLocalSize(*layout, localSize));
14599566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(*layout, 1));
14609566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(*layout));
1461ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1462ea844a1aSMatthew Knepley }
1463ea844a1aSMatthew Knepley 
1464ea844a1aSMatthew Knepley /*@
1465ea844a1aSMatthew Knepley   PetscSectionGetValueLayout - Get the PetscLayout associated with the section dofs.
1466ea844a1aSMatthew Knepley 
1467ea844a1aSMatthew Knepley   Collective on comm
1468ea844a1aSMatthew Knepley 
1469ea844a1aSMatthew Knepley   Input Parameters:
1470ea844a1aSMatthew Knepley + comm - The MPI_Comm
1471ea844a1aSMatthew Knepley - s    - The PetscSection
1472ea844a1aSMatthew Knepley 
1473ea844a1aSMatthew Knepley   Output Parameter:
1474ea844a1aSMatthew Knepley . layout - The dof layout for the section
1475ea844a1aSMatthew Knepley 
1476ea844a1aSMatthew Knepley   Note: This is usually called for the default global section.
1477ea844a1aSMatthew Knepley 
1478ea844a1aSMatthew Knepley   Level: advanced
1479ea844a1aSMatthew Knepley 
1480db781477SPatrick Sanan .seealso: `PetscSectionGetPointLayout()`, `PetscSectionCreate()`
1481ea844a1aSMatthew Knepley @*/
1482*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetValueLayout(MPI_Comm comm, PetscSection s, PetscLayout *layout) {
1483ea844a1aSMatthew Knepley   PetscInt pStart, pEnd, p, localSize = 0;
1484ea844a1aSMatthew Knepley 
1485ea844a1aSMatthew Knepley   PetscFunctionBegin;
1486ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2);
1487ea844a1aSMatthew Knepley   PetscValidPointer(layout, 3);
14889566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
1489ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1490ea844a1aSMatthew Knepley     PetscInt dof, cdof;
1491ea844a1aSMatthew Knepley 
14929566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
14939566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
1494ea844a1aSMatthew Knepley     if (dof - cdof > 0) localSize += dof - cdof;
1495ea844a1aSMatthew Knepley   }
14969566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, layout));
14979566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetLocalSize(*layout, localSize));
14989566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(*layout, 1));
14999566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(*layout));
1500ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1501ea844a1aSMatthew Knepley }
1502ea844a1aSMatthew Knepley 
1503ea844a1aSMatthew Knepley /*@
1504ea844a1aSMatthew Knepley   PetscSectionGetOffset - Return the offset into an array or local Vec for the dof associated with the given point.
1505ea844a1aSMatthew Knepley 
150640750d41SVaclav Hapla   Not Collective
1507ea844a1aSMatthew Knepley 
1508ea844a1aSMatthew Knepley   Input Parameters:
1509ea844a1aSMatthew Knepley + s - the PetscSection
1510ea844a1aSMatthew Knepley - point - the point
1511ea844a1aSMatthew Knepley 
1512ea844a1aSMatthew Knepley   Output Parameter:
1513ea844a1aSMatthew Knepley . offset - the offset
1514ea844a1aSMatthew Knepley 
1515ea844a1aSMatthew Knepley   Level: intermediate
1516ea844a1aSMatthew Knepley 
1517db781477SPatrick Sanan .seealso: `PetscSectionGetFieldOffset()`, `PetscSectionCreate()`
1518ea844a1aSMatthew Knepley @*/
1519*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetOffset(PetscSection s, PetscInt point, PetscInt *offset) {
1520ea844a1aSMatthew Knepley   PetscFunctionBegin;
1521ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1522dadcf809SJacob Faibussowitsch   PetscValidIntPointer(offset, 3);
1523*9371c9d4SSatish Balay   if (PetscDefined(USE_DEBUG)) { PetscCheck(!(point < s->pStart) && !(point >= s->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, s->pStart, s->pEnd); }
1524ea844a1aSMatthew Knepley   *offset = s->atlasOff[point - s->pStart];
1525ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1526ea844a1aSMatthew Knepley }
1527ea844a1aSMatthew Knepley 
1528ea844a1aSMatthew Knepley /*@
1529ea844a1aSMatthew Knepley   PetscSectionSetOffset - Set the offset into an array or local Vec for the dof associated with the given point.
1530ea844a1aSMatthew Knepley 
153140750d41SVaclav Hapla   Not Collective
1532ea844a1aSMatthew Knepley 
1533ea844a1aSMatthew Knepley   Input Parameters:
1534ea844a1aSMatthew Knepley + s - the PetscSection
1535ea844a1aSMatthew Knepley . point - the point
1536ea844a1aSMatthew Knepley - offset - the offset
1537ea844a1aSMatthew Knepley 
1538ea844a1aSMatthew Knepley   Note: The user usually does not call this function, but uses PetscSectionSetUp()
1539ea844a1aSMatthew Knepley 
1540ea844a1aSMatthew Knepley   Level: intermediate
1541ea844a1aSMatthew Knepley 
1542db781477SPatrick Sanan .seealso: `PetscSectionGetFieldOffset()`, `PetscSectionCreate()`, `PetscSectionSetUp()`
1543ea844a1aSMatthew Knepley @*/
1544*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetOffset(PetscSection s, PetscInt point, PetscInt offset) {
1545ea844a1aSMatthew Knepley   PetscFunctionBegin;
1546ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
154708401ef6SPierre Jolivet   PetscCheck(!(point < s->pStart) && !(point >= s->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %" PetscInt_FMT " should be in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, s->pStart, s->pEnd);
1548ea844a1aSMatthew Knepley   s->atlasOff[point - s->pStart] = offset;
1549ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1550ea844a1aSMatthew Knepley }
1551ea844a1aSMatthew Knepley 
1552ea844a1aSMatthew Knepley /*@
1553ea844a1aSMatthew Knepley   PetscSectionGetFieldOffset - Return the offset into an array or local Vec for the dof associated with the given point.
1554ea844a1aSMatthew Knepley 
155540750d41SVaclav Hapla   Not Collective
1556ea844a1aSMatthew Knepley 
1557ea844a1aSMatthew Knepley   Input Parameters:
1558ea844a1aSMatthew Knepley + s - the PetscSection
1559ea844a1aSMatthew Knepley . point - the point
1560ea844a1aSMatthew Knepley - field - the field
1561ea844a1aSMatthew Knepley 
1562ea844a1aSMatthew Knepley   Output Parameter:
1563ea844a1aSMatthew Knepley . offset - the offset
1564ea844a1aSMatthew Knepley 
1565ea844a1aSMatthew Knepley   Level: intermediate
1566ea844a1aSMatthew Knepley 
1567db781477SPatrick Sanan .seealso: `PetscSectionGetOffset()`, `PetscSectionCreate()`
1568ea844a1aSMatthew Knepley @*/
1569*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt *offset) {
1570ea844a1aSMatthew Knepley   PetscFunctionBegin;
1571ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
15722abc8c78SJacob Faibussowitsch   PetscValidIntPointer(offset, 4);
15732abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
15749566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetOffset(s->field[field], point, offset));
1575ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1576ea844a1aSMatthew Knepley }
1577ea844a1aSMatthew Knepley 
1578ea844a1aSMatthew Knepley /*@
15791681d8a4SMatthew Knepley   PetscSectionSetFieldOffset - Set the offset into an array or local Vec for the dof associated with the given field at a point.
1580ea844a1aSMatthew Knepley 
158140750d41SVaclav Hapla   Not Collective
1582ea844a1aSMatthew Knepley 
1583ea844a1aSMatthew Knepley   Input Parameters:
1584ea844a1aSMatthew Knepley + s - the PetscSection
1585ea844a1aSMatthew Knepley . point - the point
1586ea844a1aSMatthew Knepley . field - the field
1587ea844a1aSMatthew Knepley - offset - the offset
1588ea844a1aSMatthew Knepley 
1589ea844a1aSMatthew Knepley   Note: The user usually does not call this function, but uses PetscSectionSetUp()
1590ea844a1aSMatthew Knepley 
1591ea844a1aSMatthew Knepley   Level: intermediate
1592ea844a1aSMatthew Knepley 
1593db781477SPatrick Sanan .seealso: `PetscSectionGetFieldOffset()`, `PetscSectionSetOffset()`, `PetscSectionCreate()`, `PetscSectionSetUp()`
1594ea844a1aSMatthew Knepley @*/
1595*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt offset) {
1596ea844a1aSMatthew Knepley   PetscFunctionBegin;
1597ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
15982abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
15999566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetOffset(s->field[field], point, offset));
1600ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1601ea844a1aSMatthew Knepley }
1602ea844a1aSMatthew Knepley 
1603ea844a1aSMatthew Knepley /*@
1604ea844a1aSMatthew Knepley   PetscSectionGetFieldPointOffset - Return the offset on the given point for the dof associated with the given point.
1605ea844a1aSMatthew Knepley 
160640750d41SVaclav Hapla   Not Collective
1607ea844a1aSMatthew Knepley 
1608ea844a1aSMatthew Knepley   Input Parameters:
1609ea844a1aSMatthew Knepley + s - the PetscSection
1610ea844a1aSMatthew Knepley . point - the point
1611ea844a1aSMatthew Knepley - field - the field
1612ea844a1aSMatthew Knepley 
1613ea844a1aSMatthew Knepley   Output Parameter:
1614ea844a1aSMatthew Knepley . offset - the offset
1615ea844a1aSMatthew Knepley 
1616ea844a1aSMatthew Knepley   Note: This gives the offset on a point of the field, ignoring constraints, meaning starting at the first dof for
1617ea844a1aSMatthew Knepley         this point, what number is the first dof with this field.
1618ea844a1aSMatthew Knepley 
1619ea844a1aSMatthew Knepley   Level: advanced
1620ea844a1aSMatthew Knepley 
1621db781477SPatrick Sanan .seealso: `PetscSectionGetOffset()`, `PetscSectionCreate()`
1622ea844a1aSMatthew Knepley @*/
1623*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldPointOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt *offset) {
1624ea844a1aSMatthew Knepley   PetscInt off, foff;
1625ea844a1aSMatthew Knepley 
1626ea844a1aSMatthew Knepley   PetscFunctionBegin;
1627ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
16282abc8c78SJacob Faibussowitsch   PetscValidIntPointer(offset, 4);
16292abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
16309566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetOffset(s, point, &off));
16319566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetOffset(s->field[field], point, &foff));
1632ea844a1aSMatthew Knepley   *offset = foff - off;
1633ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1634ea844a1aSMatthew Knepley }
1635ea844a1aSMatthew Knepley 
1636ea844a1aSMatthew Knepley /*@
1637ea844a1aSMatthew Knepley   PetscSectionGetOffsetRange - Return the full range of offsets [start, end)
1638ea844a1aSMatthew Knepley 
163940750d41SVaclav Hapla   Not Collective
1640ea844a1aSMatthew Knepley 
1641ea844a1aSMatthew Knepley   Input Parameter:
1642ea844a1aSMatthew Knepley . s - the PetscSection
1643ea844a1aSMatthew Knepley 
1644ea844a1aSMatthew Knepley   Output Parameters:
1645ea844a1aSMatthew Knepley + start - the minimum offset
1646ea844a1aSMatthew Knepley - end   - one more than the maximum offset
1647ea844a1aSMatthew Knepley 
1648ea844a1aSMatthew Knepley   Level: intermediate
1649ea844a1aSMatthew Knepley 
1650db781477SPatrick Sanan .seealso: `PetscSectionGetOffset()`, `PetscSectionCreate()`
1651ea844a1aSMatthew Knepley @*/
1652*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetOffsetRange(PetscSection s, PetscInt *start, PetscInt *end) {
1653ea844a1aSMatthew Knepley   PetscInt os = 0, oe = 0, pStart, pEnd, p;
1654ea844a1aSMatthew Knepley 
1655ea844a1aSMatthew Knepley   PetscFunctionBegin;
1656ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1657*9371c9d4SSatish Balay   if (s->atlasOff) {
1658*9371c9d4SSatish Balay     os = s->atlasOff[0];
1659*9371c9d4SSatish Balay     oe = s->atlasOff[0];
1660*9371c9d4SSatish Balay   }
16619566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
1662ea844a1aSMatthew Knepley   for (p = 0; p < pEnd - pStart; ++p) {
1663ea844a1aSMatthew Knepley     PetscInt dof = s->atlasDof[p], off = s->atlasOff[p];
1664ea844a1aSMatthew Knepley 
1665ea844a1aSMatthew Knepley     if (off >= 0) {
1666ea844a1aSMatthew Knepley       os = PetscMin(os, off);
1667ea844a1aSMatthew Knepley       oe = PetscMax(oe, off + dof);
1668ea844a1aSMatthew Knepley     }
1669ea844a1aSMatthew Knepley   }
1670ea844a1aSMatthew Knepley   if (start) *start = os;
1671ea844a1aSMatthew Knepley   if (end) *end = oe;
1672ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1673ea844a1aSMatthew Knepley }
1674ea844a1aSMatthew Knepley 
1675ea844a1aSMatthew Knepley /*@
1676ea844a1aSMatthew Knepley   PetscSectionCreateSubsection - Create a new, smaller section composed of only the selected fields
1677ea844a1aSMatthew Knepley 
167840750d41SVaclav Hapla   Collective
1679ea844a1aSMatthew Knepley 
1680d8d19677SJose E. Roman   Input Parameters:
1681ea844a1aSMatthew Knepley + s      - the PetscSection
1682ea844a1aSMatthew Knepley . len    - the number of subfields
1683ea844a1aSMatthew Knepley - fields - the subfield numbers
1684ea844a1aSMatthew Knepley 
1685ea844a1aSMatthew Knepley   Output Parameter:
1686ea844a1aSMatthew Knepley . subs   - the subsection
1687ea844a1aSMatthew Knepley 
1688ea844a1aSMatthew Knepley   Note: The section offsets now refer to a new, smaller vector.
1689ea844a1aSMatthew Knepley 
1690ea844a1aSMatthew Knepley   Level: advanced
1691ea844a1aSMatthew Knepley 
1692db781477SPatrick Sanan .seealso: `PetscSectionCreateSupersection()`, `PetscSectionCreate()`
1693ea844a1aSMatthew Knepley @*/
1694*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateSubsection(PetscSection s, PetscInt len, const PetscInt fields[], PetscSection *subs) {
1695b778fa18SValeria Barra   PetscInt nF, f, c, pStart, pEnd, p, maxCdof = 0;
1696ea844a1aSMatthew Knepley 
1697ea844a1aSMatthew Knepley   PetscFunctionBegin;
1698ea844a1aSMatthew Knepley   if (!len) PetscFunctionReturn(0);
1699ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1700dadcf809SJacob Faibussowitsch   PetscValidIntPointer(fields, 3);
1701ea844a1aSMatthew Knepley   PetscValidPointer(subs, 4);
17029566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s, &nF));
170308401ef6SPierre Jolivet   PetscCheck(len <= nF, PetscObjectComm((PetscObject)s), PETSC_ERR_ARG_WRONG, "Number of requested fields %" PetscInt_FMT " greater than number of fields %" PetscInt_FMT, len, nF);
17049566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), subs));
17059566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetNumFields(*subs, len));
1706ea844a1aSMatthew Knepley   for (f = 0; f < len; ++f) {
1707ea844a1aSMatthew Knepley     const char *name    = NULL;
1708ea844a1aSMatthew Knepley     PetscInt    numComp = 0;
1709ea844a1aSMatthew Knepley 
17109566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldName(s, fields[f], &name));
17119566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldName(*subs, f, name));
17129566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s, fields[f], &numComp));
17139566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldComponents(*subs, f, numComp));
1714b778fa18SValeria Barra     for (c = 0; c < s->numFieldComponents[fields[f]]; ++c) {
17159566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetComponentName(s, fields[f], c, &name));
17169566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetComponentName(*subs, f, c, name));
1717b778fa18SValeria Barra     }
1718ea844a1aSMatthew Knepley   }
17199566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
17209566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(*subs, pStart, pEnd));
1721ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1722ea844a1aSMatthew Knepley     PetscInt dof = 0, cdof = 0, fdof = 0, cfdof = 0;
1723ea844a1aSMatthew Knepley 
1724ea844a1aSMatthew Knepley     for (f = 0; f < len; ++f) {
17259566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s, p, fields[f], &fdof));
17269566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldDof(*subs, p, f, fdof));
17279566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s, p, fields[f], &cfdof));
17289566063dSJacob Faibussowitsch       if (cfdof) PetscCall(PetscSectionSetFieldConstraintDof(*subs, p, f, cfdof));
1729ea844a1aSMatthew Knepley       dof += fdof;
1730ea844a1aSMatthew Knepley       cdof += cfdof;
1731ea844a1aSMatthew Knepley     }
17329566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(*subs, p, dof));
17339566063dSJacob Faibussowitsch     if (cdof) PetscCall(PetscSectionSetConstraintDof(*subs, p, cdof));
1734ea844a1aSMatthew Knepley     maxCdof = PetscMax(cdof, maxCdof);
1735ea844a1aSMatthew Knepley   }
17369566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(*subs));
1737ea844a1aSMatthew Knepley   if (maxCdof) {
1738ea844a1aSMatthew Knepley     PetscInt *indices;
1739ea844a1aSMatthew Knepley 
17409566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(maxCdof, &indices));
1741ea844a1aSMatthew Knepley     for (p = pStart; p < pEnd; ++p) {
1742ea844a1aSMatthew Knepley       PetscInt cdof;
1743ea844a1aSMatthew Knepley 
17449566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintDof(*subs, p, &cdof));
1745ea844a1aSMatthew Knepley       if (cdof) {
1746ea844a1aSMatthew Knepley         const PetscInt *oldIndices = NULL;
1747ea844a1aSMatthew Knepley         PetscInt        fdof = 0, cfdof = 0, fc, numConst = 0, fOff = 0;
1748ea844a1aSMatthew Knepley 
1749ea844a1aSMatthew Knepley         for (f = 0; f < len; ++f) {
17509566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetFieldDof(s, p, fields[f], &fdof));
17519566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetFieldConstraintDof(s, p, fields[f], &cfdof));
17529566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetFieldConstraintIndices(s, p, fields[f], &oldIndices));
17539566063dSJacob Faibussowitsch           PetscCall(PetscSectionSetFieldConstraintIndices(*subs, p, f, oldIndices));
17549574d0f0SMatthew G. Knepley           for (fc = 0; fc < cfdof; ++fc) indices[numConst + fc] = oldIndices[fc] + fOff;
1755ea844a1aSMatthew Knepley           numConst += cfdof;
1756ea844a1aSMatthew Knepley           fOff += fdof;
1757ea844a1aSMatthew Knepley         }
17589566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetConstraintIndices(*subs, p, indices));
1759ea844a1aSMatthew Knepley       }
1760ea844a1aSMatthew Knepley     }
17619566063dSJacob Faibussowitsch     PetscCall(PetscFree(indices));
1762ea844a1aSMatthew Knepley   }
1763ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1764ea844a1aSMatthew Knepley }
1765ea844a1aSMatthew Knepley 
1766ea844a1aSMatthew Knepley /*@
1767ea844a1aSMatthew Knepley   PetscSectionCreateSupersection - Create a new, larger section composed of the input sections
1768ea844a1aSMatthew Knepley 
176940750d41SVaclav Hapla   Collective
1770ea844a1aSMatthew Knepley 
1771ea844a1aSMatthew Knepley   Input Parameters:
1772ea844a1aSMatthew Knepley + s     - the input sections
1773ea844a1aSMatthew Knepley - len   - the number of input sections
1774ea844a1aSMatthew Knepley 
1775ea844a1aSMatthew Knepley   Output Parameter:
1776ea844a1aSMatthew Knepley . supers - the supersection
1777ea844a1aSMatthew Knepley 
1778ea844a1aSMatthew Knepley   Note: The section offsets now refer to a new, larger vector.
1779ea844a1aSMatthew Knepley 
1780ea844a1aSMatthew Knepley   Level: advanced
1781ea844a1aSMatthew Knepley 
1782db781477SPatrick Sanan .seealso: `PetscSectionCreateSubsection()`, `PetscSectionCreate()`
1783ea844a1aSMatthew Knepley @*/
1784*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateSupersection(PetscSection s[], PetscInt len, PetscSection *supers) {
1785ea844a1aSMatthew Knepley   PetscInt Nf = 0, f, pStart = PETSC_MAX_INT, pEnd = 0, p, maxCdof = 0, i;
1786ea844a1aSMatthew Knepley 
1787ea844a1aSMatthew Knepley   PetscFunctionBegin;
1788ea844a1aSMatthew Knepley   if (!len) PetscFunctionReturn(0);
1789ea844a1aSMatthew Knepley   for (i = 0; i < len; ++i) {
1790ea844a1aSMatthew Knepley     PetscInt nf, pStarti, pEndi;
1791ea844a1aSMatthew Knepley 
17929566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s[i], &nf));
17939566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetChart(s[i], &pStarti, &pEndi));
1794ea844a1aSMatthew Knepley     pStart = PetscMin(pStart, pStarti);
1795ea844a1aSMatthew Knepley     pEnd   = PetscMax(pEnd, pEndi);
1796ea844a1aSMatthew Knepley     Nf += nf;
1797ea844a1aSMatthew Knepley   }
17989566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s[0]), supers));
17999566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetNumFields(*supers, Nf));
1800ea844a1aSMatthew Knepley   for (i = 0, f = 0; i < len; ++i) {
1801b778fa18SValeria Barra     PetscInt nf, fi, ci;
1802ea844a1aSMatthew Knepley 
18039566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s[i], &nf));
1804ea844a1aSMatthew Knepley     for (fi = 0; fi < nf; ++fi, ++f) {
1805ea844a1aSMatthew Knepley       const char *name    = NULL;
1806ea844a1aSMatthew Knepley       PetscInt    numComp = 0;
1807ea844a1aSMatthew Knepley 
18089566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldName(s[i], fi, &name));
18099566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldName(*supers, f, name));
18109566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldComponents(s[i], fi, &numComp));
18119566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldComponents(*supers, f, numComp));
1812b778fa18SValeria Barra       for (ci = 0; ci < s[i]->numFieldComponents[fi]; ++ci) {
18139566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetComponentName(s[i], fi, ci, &name));
18149566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetComponentName(*supers, f, ci, name));
1815b778fa18SValeria Barra       }
1816ea844a1aSMatthew Knepley     }
1817ea844a1aSMatthew Knepley   }
18189566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(*supers, pStart, pEnd));
1819ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1820ea844a1aSMatthew Knepley     PetscInt dof = 0, cdof = 0;
1821ea844a1aSMatthew Knepley 
1822ea844a1aSMatthew Knepley     for (i = 0, f = 0; i < len; ++i) {
1823ea844a1aSMatthew Knepley       PetscInt nf, fi, pStarti, pEndi;
1824ea844a1aSMatthew Knepley       PetscInt fdof = 0, cfdof = 0;
1825ea844a1aSMatthew Knepley 
18269566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetNumFields(s[i], &nf));
18279566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetChart(s[i], &pStarti, &pEndi));
1828ea844a1aSMatthew Knepley       if ((p < pStarti) || (p >= pEndi)) continue;
1829ea844a1aSMatthew Knepley       for (fi = 0; fi < nf; ++fi, ++f) {
18309566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldDof(s[i], p, fi, &fdof));
18319566063dSJacob Faibussowitsch         PetscCall(PetscSectionAddFieldDof(*supers, p, f, fdof));
18329566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldConstraintDof(s[i], p, fi, &cfdof));
18339566063dSJacob Faibussowitsch         if (cfdof) PetscCall(PetscSectionAddFieldConstraintDof(*supers, p, f, cfdof));
1834ea844a1aSMatthew Knepley         dof += fdof;
1835ea844a1aSMatthew Knepley         cdof += cfdof;
1836ea844a1aSMatthew Knepley       }
1837ea844a1aSMatthew Knepley     }
18389566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(*supers, p, dof));
18399566063dSJacob Faibussowitsch     if (cdof) PetscCall(PetscSectionSetConstraintDof(*supers, p, cdof));
1840ea844a1aSMatthew Knepley     maxCdof = PetscMax(cdof, maxCdof);
1841ea844a1aSMatthew Knepley   }
18429566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(*supers));
1843ea844a1aSMatthew Knepley   if (maxCdof) {
1844ea844a1aSMatthew Knepley     PetscInt *indices;
1845ea844a1aSMatthew Knepley 
18469566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(maxCdof, &indices));
1847ea844a1aSMatthew Knepley     for (p = pStart; p < pEnd; ++p) {
1848ea844a1aSMatthew Knepley       PetscInt cdof;
1849ea844a1aSMatthew Knepley 
18509566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintDof(*supers, p, &cdof));
1851ea844a1aSMatthew Knepley       if (cdof) {
1852ea844a1aSMatthew Knepley         PetscInt dof, numConst = 0, fOff = 0;
1853ea844a1aSMatthew Knepley 
1854ea844a1aSMatthew Knepley         for (i = 0, f = 0; i < len; ++i) {
1855ea844a1aSMatthew Knepley           const PetscInt *oldIndices = NULL;
1856ea844a1aSMatthew Knepley           PetscInt        nf, fi, pStarti, pEndi, fdof, cfdof, fc;
1857ea844a1aSMatthew Knepley 
18589566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetNumFields(s[i], &nf));
18599566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetChart(s[i], &pStarti, &pEndi));
1860ea844a1aSMatthew Knepley           if ((p < pStarti) || (p >= pEndi)) continue;
1861ea844a1aSMatthew Knepley           for (fi = 0; fi < nf; ++fi, ++f) {
18629566063dSJacob Faibussowitsch             PetscCall(PetscSectionGetFieldDof(s[i], p, fi, &fdof));
18639566063dSJacob Faibussowitsch             PetscCall(PetscSectionGetFieldConstraintDof(s[i], p, fi, &cfdof));
18649566063dSJacob Faibussowitsch             PetscCall(PetscSectionGetFieldConstraintIndices(s[i], p, fi, &oldIndices));
1865fcd2503dSMatthew G. Knepley             for (fc = 0; fc < cfdof; ++fc) indices[numConst + fc] = oldIndices[fc];
18669566063dSJacob Faibussowitsch             PetscCall(PetscSectionSetFieldConstraintIndices(*supers, p, f, &indices[numConst]));
1867fcd2503dSMatthew G. Knepley             for (fc = 0; fc < cfdof; ++fc) indices[numConst + fc] += fOff;
1868ea844a1aSMatthew Knepley             numConst += cfdof;
1869ea844a1aSMatthew Knepley           }
18709566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetDof(s[i], p, &dof));
1871ea844a1aSMatthew Knepley           fOff += dof;
1872ea844a1aSMatthew Knepley         }
18739566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetConstraintIndices(*supers, p, indices));
1874ea844a1aSMatthew Knepley       }
1875ea844a1aSMatthew Knepley     }
18769566063dSJacob Faibussowitsch     PetscCall(PetscFree(indices));
1877ea844a1aSMatthew Knepley   }
1878ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1879ea844a1aSMatthew Knepley }
1880ea844a1aSMatthew Knepley 
1881*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateSubplexSection_Internal(PetscSection s, IS subpointMap, PetscBool renumberPoints, PetscSection *subs) {
1882ea844a1aSMatthew Knepley   const PetscInt *points = NULL, *indices = NULL;
188341f23ed0SMatthew G. Knepley   PetscInt        numFields, f, c, numSubpoints = 0, pStart, pEnd, p, spStart, spEnd, subp;
1884ea844a1aSMatthew Knepley 
1885ea844a1aSMatthew Knepley   PetscFunctionBegin;
1886ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1887ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(subpointMap, IS_CLASSID, 2);
188841f23ed0SMatthew G. Knepley   PetscValidPointer(subs, 4);
18899566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s, &numFields));
18909566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), subs));
18919566063dSJacob Faibussowitsch   if (numFields) PetscCall(PetscSectionSetNumFields(*subs, numFields));
1892ea844a1aSMatthew Knepley   for (f = 0; f < numFields; ++f) {
1893ea844a1aSMatthew Knepley     const char *name    = NULL;
1894ea844a1aSMatthew Knepley     PetscInt    numComp = 0;
1895ea844a1aSMatthew Knepley 
18969566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldName(s, f, &name));
18979566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldName(*subs, f, name));
18989566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s, f, &numComp));
18999566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldComponents(*subs, f, numComp));
1900b778fa18SValeria Barra     for (c = 0; c < s->numFieldComponents[f]; ++c) {
19019566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetComponentName(s, f, c, &name));
19029566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetComponentName(*subs, f, c, name));
1903b778fa18SValeria Barra     }
1904ea844a1aSMatthew Knepley   }
1905ea844a1aSMatthew Knepley   /* For right now, we do not try to squeeze the subchart */
1906ea844a1aSMatthew Knepley   if (subpointMap) {
19079566063dSJacob Faibussowitsch     PetscCall(ISGetSize(subpointMap, &numSubpoints));
19089566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(subpointMap, &points));
1909ea844a1aSMatthew Knepley   }
19109566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
191141f23ed0SMatthew G. Knepley   if (renumberPoints) {
191241f23ed0SMatthew G. Knepley     spStart = 0;
191341f23ed0SMatthew G. Knepley     spEnd   = numSubpoints;
191441f23ed0SMatthew G. Knepley   } else {
191541f23ed0SMatthew G. Knepley     PetscCall(ISGetMinMax(subpointMap, &spStart, &spEnd));
191641f23ed0SMatthew G. Knepley     ++spEnd;
191741f23ed0SMatthew G. Knepley   }
191841f23ed0SMatthew G. Knepley   PetscCall(PetscSectionSetChart(*subs, spStart, spEnd));
1919ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1920ea844a1aSMatthew Knepley     PetscInt dof, cdof, fdof = 0, cfdof = 0;
1921ea844a1aSMatthew Knepley 
19229566063dSJacob Faibussowitsch     PetscCall(PetscFindInt(p, numSubpoints, points, &subp));
1923ea844a1aSMatthew Knepley     if (subp < 0) continue;
192441f23ed0SMatthew G. Knepley     if (!renumberPoints) subp = p;
1925ea844a1aSMatthew Knepley     for (f = 0; f < numFields; ++f) {
19269566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s, p, f, &fdof));
19279566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldDof(*subs, subp, f, fdof));
19289566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &cfdof));
19299566063dSJacob Faibussowitsch       if (cfdof) PetscCall(PetscSectionSetFieldConstraintDof(*subs, subp, f, cfdof));
1930ea844a1aSMatthew Knepley     }
19319566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
19329566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(*subs, subp, dof));
19339566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
19349566063dSJacob Faibussowitsch     if (cdof) PetscCall(PetscSectionSetConstraintDof(*subs, subp, cdof));
1935ea844a1aSMatthew Knepley   }
19369566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(*subs));
1937ea844a1aSMatthew Knepley   /* Change offsets to original offsets */
1938ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
1939ea844a1aSMatthew Knepley     PetscInt off, foff = 0;
1940ea844a1aSMatthew Knepley 
19419566063dSJacob Faibussowitsch     PetscCall(PetscFindInt(p, numSubpoints, points, &subp));
1942ea844a1aSMatthew Knepley     if (subp < 0) continue;
194341f23ed0SMatthew G. Knepley     if (!renumberPoints) subp = p;
1944ea844a1aSMatthew Knepley     for (f = 0; f < numFields; ++f) {
19459566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldOffset(s, p, f, &foff));
19469566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldOffset(*subs, subp, f, foff));
1947ea844a1aSMatthew Knepley     }
19489566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(s, p, &off));
19499566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetOffset(*subs, subp, off));
1950ea844a1aSMatthew Knepley   }
1951ea844a1aSMatthew Knepley   /* Copy constraint indices */
195241f23ed0SMatthew G. Knepley   for (subp = spStart; subp < spEnd; ++subp) {
1953ea844a1aSMatthew Knepley     PetscInt cdof;
1954ea844a1aSMatthew Knepley 
19559566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(*subs, subp, &cdof));
1956ea844a1aSMatthew Knepley     if (cdof) {
1957ea844a1aSMatthew Knepley       for (f = 0; f < numFields; ++f) {
195841f23ed0SMatthew G. Knepley         PetscCall(PetscSectionGetFieldConstraintIndices(s, points[subp - spStart], f, &indices));
19599566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetFieldConstraintIndices(*subs, subp, f, indices));
1960ea844a1aSMatthew Knepley       }
196141f23ed0SMatthew G. Knepley       PetscCall(PetscSectionGetConstraintIndices(s, points[subp - spStart], &indices));
19629566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetConstraintIndices(*subs, subp, indices));
1963ea844a1aSMatthew Knepley     }
1964ea844a1aSMatthew Knepley   }
19659566063dSJacob Faibussowitsch   if (subpointMap) PetscCall(ISRestoreIndices(subpointMap, &points));
1966ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
1967ea844a1aSMatthew Knepley }
1968ea844a1aSMatthew Knepley 
196941f23ed0SMatthew G. Knepley /*@
197041f23ed0SMatthew G. Knepley   PetscSectionCreateSubmeshSection - Create a new, smaller section with support on the submesh
197141f23ed0SMatthew G. Knepley 
197241f23ed0SMatthew G. Knepley   Collective on s
197341f23ed0SMatthew G. Knepley 
197441f23ed0SMatthew G. Knepley   Input Parameters:
197541f23ed0SMatthew G. Knepley + s           - the PetscSection
197641f23ed0SMatthew G. Knepley - subpointMap - a sorted list of points in the original mesh which are in the submesh
197741f23ed0SMatthew G. Knepley 
197841f23ed0SMatthew G. Knepley   Output Parameter:
197941f23ed0SMatthew G. Knepley . subs - the subsection
198041f23ed0SMatthew G. Knepley 
198141f23ed0SMatthew G. Knepley   Note:
198241f23ed0SMatthew G. Knepley   The points are renumbered from 0, and the section offsets now refer to a new, smaller vector.
198341f23ed0SMatthew G. Knepley 
198441f23ed0SMatthew G. Knepley   Level: advanced
198541f23ed0SMatthew G. Knepley 
1986db781477SPatrick Sanan .seealso: `PetscSectionCreateSubdomainSection()`, `PetscSectionCreateSubsection()`, `DMPlexGetSubpointMap()`, `PetscSectionCreate()`
198741f23ed0SMatthew G. Knepley @*/
1988*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateSubmeshSection(PetscSection s, IS subpointMap, PetscSection *subs) {
198941f23ed0SMatthew G. Knepley   PetscFunctionBegin;
199041f23ed0SMatthew G. Knepley   PetscCall(PetscSectionCreateSubplexSection_Internal(s, subpointMap, PETSC_TRUE, subs));
199141f23ed0SMatthew G. Knepley   PetscFunctionReturn(0);
199241f23ed0SMatthew G. Knepley }
199341f23ed0SMatthew G. Knepley 
199441f23ed0SMatthew G. Knepley /*@
199541f23ed0SMatthew G. Knepley   PetscSectionCreateSubdomainSection - Create a new, smaller section with support on a subdomain of the mesh
199641f23ed0SMatthew G. Knepley 
199741f23ed0SMatthew G. Knepley   Collective on s
199841f23ed0SMatthew G. Knepley 
199941f23ed0SMatthew G. Knepley   Input Parameters:
200041f23ed0SMatthew G. Knepley + s           - the PetscSection
200141f23ed0SMatthew G. Knepley - subpointMap - a sorted list of points in the original mesh which are in the subdomain
200241f23ed0SMatthew G. Knepley 
200341f23ed0SMatthew G. Knepley   Output Parameter:
200441f23ed0SMatthew G. Knepley . subs - the subsection
200541f23ed0SMatthew G. Knepley 
200641f23ed0SMatthew G. Knepley   Note:
200741f23ed0SMatthew G. Knepley   The point numbers remain the same, but the section offsets now refer to a new, smaller vector.
200841f23ed0SMatthew G. Knepley 
200941f23ed0SMatthew G. Knepley   Level: advanced
201041f23ed0SMatthew G. Knepley 
2011db781477SPatrick Sanan .seealso: `PetscSectionCreateSubmeshSection()`, `PetscSectionCreateSubsection()`, `DMPlexGetSubpointMap()`, `PetscSectionCreate()`
201241f23ed0SMatthew G. Knepley @*/
2013*9371c9d4SSatish Balay PetscErrorCode PetscSectionCreateSubdomainSection(PetscSection s, IS subpointMap, PetscSection *subs) {
201441f23ed0SMatthew G. Knepley   PetscFunctionBegin;
201541f23ed0SMatthew G. Knepley   PetscCall(PetscSectionCreateSubplexSection_Internal(s, subpointMap, PETSC_FALSE, subs));
201641f23ed0SMatthew G. Knepley   PetscFunctionReturn(0);
201741f23ed0SMatthew G. Knepley }
201841f23ed0SMatthew G. Knepley 
2019*9371c9d4SSatish Balay static PetscErrorCode PetscSectionView_ASCII(PetscSection s, PetscViewer viewer) {
2020ea844a1aSMatthew Knepley   PetscInt    p;
2021ea844a1aSMatthew Knepley   PetscMPIInt rank;
2022ea844a1aSMatthew Knepley 
2023ea844a1aSMatthew Knepley   PetscFunctionBegin;
20249566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
20259566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
20269566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "Process %d:\n", rank));
2027ea844a1aSMatthew Knepley   for (p = 0; p < s->pEnd - s->pStart; ++p) {
2028ea844a1aSMatthew Knepley     if ((s->bc) && (s->bc->atlasDof[p] > 0)) {
2029ea844a1aSMatthew Knepley       PetscInt b;
2030ea844a1aSMatthew Knepley 
20319566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "  (%4" PetscInt_FMT ") dim %2" PetscInt_FMT " offset %3" PetscInt_FMT " constrained", p + s->pStart, s->atlasDof[p], s->atlasOff[p]));
2032083401c6SMatthew G. Knepley       if (s->bcIndices) {
2033*9371c9d4SSatish Balay         for (b = 0; b < s->bc->atlasDof[p]; ++b) { PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, s->bcIndices[s->bc->atlasOff[p] + b])); }
2034083401c6SMatthew G. Knepley       }
20359566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
2036ea844a1aSMatthew Knepley     } else {
20379566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "  (%4" PetscInt_FMT ") dim %2" PetscInt_FMT " offset %3" PetscInt_FMT "\n", p + s->pStart, s->atlasDof[p], s->atlasOff[p]));
2038ea844a1aSMatthew Knepley     }
2039ea844a1aSMatthew Knepley   }
20409566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
20419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
2042ea844a1aSMatthew Knepley   if (s->sym) {
20439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20449566063dSJacob Faibussowitsch     PetscCall(PetscSectionSymView(s->sym, viewer));
20459566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2046ea844a1aSMatthew Knepley   }
2047ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2048ea844a1aSMatthew Knepley }
2049ea844a1aSMatthew Knepley 
2050ea844a1aSMatthew Knepley /*@C
2051fe2efc57SMark    PetscSectionViewFromOptions - View from Options
2052fe2efc57SMark 
205340750d41SVaclav Hapla    Collective
2054fe2efc57SMark 
2055fe2efc57SMark    Input Parameters:
2056fe2efc57SMark +  A - the PetscSection object to view
2057736c3998SJose E. Roman .  obj - Optional object
2058736c3998SJose E. Roman -  name - command line option
2059fe2efc57SMark 
2060fe2efc57SMark    Level: intermediate
2061db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionView`, `PetscObjectViewFromOptions()`, `PetscSectionCreate()`
2062fe2efc57SMark @*/
2063*9371c9d4SSatish Balay PetscErrorCode PetscSectionViewFromOptions(PetscSection A, PetscObject obj, const char name[]) {
2064fe2efc57SMark   PetscFunctionBegin;
2065fe2efc57SMark   PetscValidHeaderSpecific(A, PETSC_SECTION_CLASSID, 1);
20669566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2067fe2efc57SMark   PetscFunctionReturn(0);
2068fe2efc57SMark }
2069fe2efc57SMark 
2070fe2efc57SMark /*@C
2071ea844a1aSMatthew Knepley   PetscSectionView - Views a PetscSection
2072ea844a1aSMatthew Knepley 
207340750d41SVaclav Hapla   Collective
2074ea844a1aSMatthew Knepley 
2075ea844a1aSMatthew Knepley   Input Parameters:
2076ea844a1aSMatthew Knepley + s - the PetscSection object to view
2077ea844a1aSMatthew Knepley - v - the viewer
2078ea844a1aSMatthew Knepley 
20791ddd528eSksagiyam   Note:
20801ddd528eSksagiyam   PetscSectionView(), when viewer is of type PETSCVIEWERHDF5, only saves
20811ddd528eSksagiyam   distribution independent data, such as dofs, offsets, constraint dofs,
20821ddd528eSksagiyam   and constraint indices. Points that have negative dofs, for instance,
20831ddd528eSksagiyam   are not saved as they represent points owned by other processes.
20841ddd528eSksagiyam   Point numbering and rank assignment is currently not stored.
20851ddd528eSksagiyam   The saved section can be loaded with PetscSectionLoad().
20861ddd528eSksagiyam 
2087ea844a1aSMatthew Knepley   Level: beginner
2088ea844a1aSMatthew Knepley 
2089db781477SPatrick Sanan .seealso `PetscSectionCreate()`, `PetscSectionDestroy()`, `PetscSectionLoad()`
2090ea844a1aSMatthew Knepley @*/
2091*9371c9d4SSatish Balay PetscErrorCode PetscSectionView(PetscSection s, PetscViewer viewer) {
20921ddd528eSksagiyam   PetscBool isascii, ishdf5;
2093ea844a1aSMatthew Knepley   PetscInt  f;
2094ea844a1aSMatthew Knepley 
2095ea844a1aSMatthew Knepley   PetscFunctionBegin;
2096ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
20979566063dSJacob Faibussowitsch   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)s), &viewer));
2098ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
20999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
21009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
2101ea844a1aSMatthew Knepley   if (isascii) {
21029566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)s, viewer));
2103ea844a1aSMatthew Knepley     if (s->numFields) {
21049566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " fields\n", s->numFields));
2105ea844a1aSMatthew Knepley       for (f = 0; f < s->numFields; ++f) {
21069566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  field %" PetscInt_FMT " with %" PetscInt_FMT " components\n", f, s->numFieldComponents[f]));
21079566063dSJacob Faibussowitsch         PetscCall(PetscSectionView_ASCII(s->field[f], viewer));
2108ea844a1aSMatthew Knepley       }
2109ea844a1aSMatthew Knepley     } else {
21109566063dSJacob Faibussowitsch       PetscCall(PetscSectionView_ASCII(s, viewer));
2111ea844a1aSMatthew Knepley     }
21121ddd528eSksagiyam   } else if (ishdf5) {
21131ddd528eSksagiyam #if PetscDefined(HAVE_HDF5)
21149566063dSJacob Faibussowitsch     PetscCall(PetscSectionView_HDF5_Internal(s, viewer));
21151ddd528eSksagiyam #else
21161ddd528eSksagiyam     SETERRQ(PetscObjectComm((PetscObject)s), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
21171ddd528eSksagiyam #endif
2118ea844a1aSMatthew Knepley   }
2119ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2120ea844a1aSMatthew Knepley }
2121ea844a1aSMatthew Knepley 
2122fde5e3acSksagiyam /*@C
2123fde5e3acSksagiyam   PetscSectionLoad - Loads a PetscSection
2124fde5e3acSksagiyam 
212540750d41SVaclav Hapla   Collective
2126fde5e3acSksagiyam 
2127fde5e3acSksagiyam   Input Parameters:
2128fde5e3acSksagiyam + s - the PetscSection object to load
2129fde5e3acSksagiyam - v - the viewer
2130fde5e3acSksagiyam 
2131fde5e3acSksagiyam   Note:
2132fde5e3acSksagiyam   PetscSectionLoad(), when viewer is of type PETSCVIEWERHDF5, loads
2133fde5e3acSksagiyam   a section saved with PetscSectionView(). The number of processes
2134fde5e3acSksagiyam   used here (N) does not need to be the same as that used when saving.
2135fde5e3acSksagiyam   After calling this function, the chart of s on rank i will be set
2136fde5e3acSksagiyam   to [0, E_i), where \sum_{i=0}^{N-1}E_i equals to the total number of
2137fde5e3acSksagiyam   saved section points.
2138fde5e3acSksagiyam 
2139fde5e3acSksagiyam   Level: beginner
2140fde5e3acSksagiyam 
2141db781477SPatrick Sanan .seealso `PetscSectionCreate()`, `PetscSectionDestroy()`, `PetscSectionView()`
2142fde5e3acSksagiyam @*/
2143*9371c9d4SSatish Balay PetscErrorCode PetscSectionLoad(PetscSection s, PetscViewer viewer) {
2144fde5e3acSksagiyam   PetscBool ishdf5;
2145fde5e3acSksagiyam 
2146fde5e3acSksagiyam   PetscFunctionBegin;
2147fde5e3acSksagiyam   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2148fde5e3acSksagiyam   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
21499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
2150fde5e3acSksagiyam   if (ishdf5) {
2151fde5e3acSksagiyam #if PetscDefined(HAVE_HDF5)
21529566063dSJacob Faibussowitsch     PetscCall(PetscSectionLoad_HDF5_Internal(s, viewer));
2153fde5e3acSksagiyam     PetscFunctionReturn(0);
2154fde5e3acSksagiyam #else
2155fde5e3acSksagiyam     SETERRQ(PetscObjectComm((PetscObject)s), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
2156fde5e3acSksagiyam #endif
215798921bdaSJacob Faibussowitsch   } else SETERRQ(PetscObjectComm((PetscObject)s), PETSC_ERR_SUP, "Viewer type %s not yet supported for PetscSection loading", ((PetscObject)viewer)->type_name);
2158fde5e3acSksagiyam }
2159fde5e3acSksagiyam 
2160*9371c9d4SSatish Balay static PetscErrorCode PetscSectionResetClosurePermutation(PetscSection section) {
2161c459fbc1SJed Brown   PetscSectionClosurePermVal clVal;
2162c459fbc1SJed Brown 
2163c459fbc1SJed Brown   PetscFunctionBegin;
2164c459fbc1SJed Brown   if (!section->clHash) PetscFunctionReturn(0);
2165c459fbc1SJed Brown   kh_foreach_value(section->clHash, clVal, {
21669566063dSJacob Faibussowitsch     PetscCall(PetscFree(clVal.perm));
21679566063dSJacob Faibussowitsch     PetscCall(PetscFree(clVal.invPerm));
2168c459fbc1SJed Brown   });
2169c459fbc1SJed Brown   kh_destroy(ClPerm, section->clHash);
2170c459fbc1SJed Brown   section->clHash = NULL;
2171c459fbc1SJed Brown   PetscFunctionReturn(0);
2172c459fbc1SJed Brown }
2173c459fbc1SJed Brown 
2174ea844a1aSMatthew Knepley /*@
2175ea844a1aSMatthew Knepley   PetscSectionReset - Frees all section data.
2176ea844a1aSMatthew Knepley 
217740750d41SVaclav Hapla   Not Collective
2178ea844a1aSMatthew Knepley 
2179ea844a1aSMatthew Knepley   Input Parameters:
2180ea844a1aSMatthew Knepley . s - the PetscSection
2181ea844a1aSMatthew Knepley 
2182ea844a1aSMatthew Knepley   Level: beginner
2183ea844a1aSMatthew Knepley 
2184db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`
2185ea844a1aSMatthew Knepley @*/
2186*9371c9d4SSatish Balay PetscErrorCode PetscSectionReset(PetscSection s) {
2187b778fa18SValeria Barra   PetscInt f, c;
2188ea844a1aSMatthew Knepley 
2189ea844a1aSMatthew Knepley   PetscFunctionBegin;
2190ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2191ea844a1aSMatthew Knepley   for (f = 0; f < s->numFields; ++f) {
21929566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&s->field[f]));
21939566063dSJacob Faibussowitsch     PetscCall(PetscFree(s->fieldNames[f]));
2194*9371c9d4SSatish Balay     for (c = 0; c < s->numFieldComponents[f]; ++c) { PetscCall(PetscFree(s->compNames[f][c])); }
21959566063dSJacob Faibussowitsch     PetscCall(PetscFree(s->compNames[f]));
2196ea844a1aSMatthew Knepley   }
21979566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->numFieldComponents));
21989566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->fieldNames));
21999566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->compNames));
22009566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->field));
22019566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&s->bc));
22029566063dSJacob Faibussowitsch   PetscCall(PetscFree(s->bcIndices));
22039566063dSJacob Faibussowitsch   PetscCall(PetscFree2(s->atlasDof, s->atlasOff));
22049566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&s->clSection));
22059566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&s->clPoints));
22069566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&s->perm));
22079566063dSJacob Faibussowitsch   PetscCall(PetscSectionResetClosurePermutation(s));
22089566063dSJacob Faibussowitsch   PetscCall(PetscSectionSymDestroy(&s->sym));
22099566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&s->clSection));
22109566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&s->clPoints));
221169c11d05SVaclav Hapla   PetscCall(PetscSectionInvalidateMaxDof_Internal(s));
2212ea844a1aSMatthew Knepley   s->pStart    = -1;
2213ea844a1aSMatthew Knepley   s->pEnd      = -1;
2214ea844a1aSMatthew Knepley   s->maxDof    = 0;
2215ea844a1aSMatthew Knepley   s->setup     = PETSC_FALSE;
2216ea844a1aSMatthew Knepley   s->numFields = 0;
2217ea844a1aSMatthew Knepley   s->clObj     = NULL;
2218ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2219ea844a1aSMatthew Knepley }
2220ea844a1aSMatthew Knepley 
2221ea844a1aSMatthew Knepley /*@
2222ea844a1aSMatthew Knepley   PetscSectionDestroy - Frees a section object and frees its range if that exists.
2223ea844a1aSMatthew Knepley 
222440750d41SVaclav Hapla   Not Collective
2225ea844a1aSMatthew Knepley 
2226ea844a1aSMatthew Knepley   Input Parameters:
2227ea844a1aSMatthew Knepley . s - the PetscSection
2228ea844a1aSMatthew Knepley 
2229ea844a1aSMatthew Knepley   Level: beginner
2230ea844a1aSMatthew Knepley 
2231db781477SPatrick Sanan .seealso: `PetscSection`, `PetscSectionCreate()`
2232ea844a1aSMatthew Knepley @*/
2233*9371c9d4SSatish Balay PetscErrorCode PetscSectionDestroy(PetscSection *s) {
2234ea844a1aSMatthew Knepley   PetscFunctionBegin;
2235ea844a1aSMatthew Knepley   if (!*s) PetscFunctionReturn(0);
223662f17a49SStefano Zampini   PetscValidHeaderSpecific(*s, PETSC_SECTION_CLASSID, 1);
2237ea844a1aSMatthew Knepley   if (--((PetscObject)(*s))->refct > 0) {
2238ea844a1aSMatthew Knepley     *s = NULL;
2239ea844a1aSMatthew Knepley     PetscFunctionReturn(0);
2240ea844a1aSMatthew Knepley   }
22419566063dSJacob Faibussowitsch   PetscCall(PetscSectionReset(*s));
22429566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(s));
2243ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2244ea844a1aSMatthew Knepley }
2245ea844a1aSMatthew Knepley 
2246*9371c9d4SSatish Balay PetscErrorCode VecIntGetValuesSection(PetscInt *baseArray, PetscSection s, PetscInt point, const PetscInt **values) {
2247ea844a1aSMatthew Knepley   const PetscInt p = point - s->pStart;
2248ea844a1aSMatthew Knepley 
2249ea844a1aSMatthew Knepley   PetscFunctionBegin;
2250ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2);
2251ea844a1aSMatthew Knepley   *values = &baseArray[s->atlasOff[p]];
2252ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2253ea844a1aSMatthew Knepley }
2254ea844a1aSMatthew Knepley 
2255*9371c9d4SSatish Balay PetscErrorCode VecIntSetValuesSection(PetscInt *baseArray, PetscSection s, PetscInt point, const PetscInt values[], InsertMode mode) {
2256ea844a1aSMatthew Knepley   PetscInt      *array;
2257ea844a1aSMatthew Knepley   const PetscInt p           = point - s->pStart;
2258ea844a1aSMatthew Knepley   const PetscInt orientation = 0; /* Needs to be included for use in closure operations */
2259ea844a1aSMatthew Knepley   PetscInt       cDim        = 0;
2260ea844a1aSMatthew Knepley 
2261ea844a1aSMatthew Knepley   PetscFunctionBegin;
2262ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2);
22639566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetConstraintDof(s, p, &cDim));
2264ea844a1aSMatthew Knepley   array = &baseArray[s->atlasOff[p]];
2265ea844a1aSMatthew Knepley   if (!cDim) {
2266ea844a1aSMatthew Knepley     if (orientation >= 0) {
2267ea844a1aSMatthew Knepley       const PetscInt dim = s->atlasDof[p];
2268ea844a1aSMatthew Knepley       PetscInt       i;
2269ea844a1aSMatthew Knepley 
2270ea844a1aSMatthew Knepley       if (mode == INSERT_VALUES) {
2271ea844a1aSMatthew Knepley         for (i = 0; i < dim; ++i) array[i] = values[i];
2272ea844a1aSMatthew Knepley       } else {
2273ea844a1aSMatthew Knepley         for (i = 0; i < dim; ++i) array[i] += values[i];
2274ea844a1aSMatthew Knepley       }
2275ea844a1aSMatthew Knepley     } else {
2276ea844a1aSMatthew Knepley       PetscInt offset = 0;
2277ea844a1aSMatthew Knepley       PetscInt j      = -1, field, i;
2278ea844a1aSMatthew Knepley 
2279ea844a1aSMatthew Knepley       for (field = 0; field < s->numFields; ++field) {
2280ea844a1aSMatthew Knepley         const PetscInt dim = s->field[field]->atlasDof[p];
2281ea844a1aSMatthew Knepley 
2282ea844a1aSMatthew Knepley         for (i = dim - 1; i >= 0; --i) array[++j] = values[i + offset];
2283ea844a1aSMatthew Knepley         offset += dim;
2284ea844a1aSMatthew Knepley       }
2285ea844a1aSMatthew Knepley     }
2286ea844a1aSMatthew Knepley   } else {
2287ea844a1aSMatthew Knepley     if (orientation >= 0) {
2288ea844a1aSMatthew Knepley       const PetscInt  dim  = s->atlasDof[p];
2289ea844a1aSMatthew Knepley       PetscInt        cInd = 0, i;
2290ea844a1aSMatthew Knepley       const PetscInt *cDof;
2291ea844a1aSMatthew Knepley 
22929566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintIndices(s, point, &cDof));
2293ea844a1aSMatthew Knepley       if (mode == INSERT_VALUES) {
2294ea844a1aSMatthew Knepley         for (i = 0; i < dim; ++i) {
2295*9371c9d4SSatish Balay           if ((cInd < cDim) && (i == cDof[cInd])) {
2296*9371c9d4SSatish Balay             ++cInd;
2297*9371c9d4SSatish Balay             continue;
2298*9371c9d4SSatish Balay           }
2299ea844a1aSMatthew Knepley           array[i] = values[i];
2300ea844a1aSMatthew Knepley         }
2301ea844a1aSMatthew Knepley       } else {
2302ea844a1aSMatthew Knepley         for (i = 0; i < dim; ++i) {
2303*9371c9d4SSatish Balay           if ((cInd < cDim) && (i == cDof[cInd])) {
2304*9371c9d4SSatish Balay             ++cInd;
2305*9371c9d4SSatish Balay             continue;
2306*9371c9d4SSatish Balay           }
2307ea844a1aSMatthew Knepley           array[i] += values[i];
2308ea844a1aSMatthew Knepley         }
2309ea844a1aSMatthew Knepley       }
2310ea844a1aSMatthew Knepley     } else {
2311ea844a1aSMatthew Knepley       const PetscInt *cDof;
2312ea844a1aSMatthew Knepley       PetscInt        offset  = 0;
2313ea844a1aSMatthew Knepley       PetscInt        cOffset = 0;
2314ea844a1aSMatthew Knepley       PetscInt        j       = 0, field;
2315ea844a1aSMatthew Knepley 
23169566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintIndices(s, point, &cDof));
2317ea844a1aSMatthew Knepley       for (field = 0; field < s->numFields; ++field) {
2318ea844a1aSMatthew Knepley         const PetscInt dim  = s->field[field]->atlasDof[p];     /* PetscSectionGetFieldDof() */
2319ea844a1aSMatthew Knepley         const PetscInt tDim = s->field[field]->bc->atlasDof[p]; /* PetscSectionGetFieldConstraintDof() */
2320ea844a1aSMatthew Knepley         const PetscInt sDim = dim - tDim;
2321ea844a1aSMatthew Knepley         PetscInt       cInd = 0, i, k;
2322ea844a1aSMatthew Knepley 
2323ea844a1aSMatthew Knepley         for (i = 0, k = dim + offset - 1; i < dim; ++i, ++j, --k) {
2324*9371c9d4SSatish Balay           if ((cInd < sDim) && (j == cDof[cInd + cOffset])) {
2325*9371c9d4SSatish Balay             ++cInd;
2326*9371c9d4SSatish Balay             continue;
2327*9371c9d4SSatish Balay           }
2328ea844a1aSMatthew Knepley           array[j] = values[k];
2329ea844a1aSMatthew Knepley         }
2330ea844a1aSMatthew Knepley         offset += dim;
2331ea844a1aSMatthew Knepley         cOffset += dim - tDim;
2332ea844a1aSMatthew Knepley       }
2333ea844a1aSMatthew Knepley     }
2334ea844a1aSMatthew Knepley   }
2335ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2336ea844a1aSMatthew Knepley }
2337ea844a1aSMatthew Knepley 
2338ea844a1aSMatthew Knepley /*@C
2339ea844a1aSMatthew Knepley   PetscSectionHasConstraints - Determine whether a section has constrained dofs
2340ea844a1aSMatthew Knepley 
234140750d41SVaclav Hapla   Not Collective
2342ea844a1aSMatthew Knepley 
2343ea844a1aSMatthew Knepley   Input Parameter:
2344ea844a1aSMatthew Knepley . s - The PetscSection
2345ea844a1aSMatthew Knepley 
2346ea844a1aSMatthew Knepley   Output Parameter:
2347ea844a1aSMatthew Knepley . hasConstraints - flag indicating that the section has constrained dofs
2348ea844a1aSMatthew Knepley 
2349ea844a1aSMatthew Knepley   Level: intermediate
2350ea844a1aSMatthew Knepley 
2351db781477SPatrick Sanan .seealso: `PetscSectionSetConstraintIndices()`, `PetscSectionGetConstraintDof()`, `PetscSection`
2352ea844a1aSMatthew Knepley @*/
2353*9371c9d4SSatish Balay PetscErrorCode PetscSectionHasConstraints(PetscSection s, PetscBool *hasConstraints) {
2354ea844a1aSMatthew Knepley   PetscFunctionBegin;
2355ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2356dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(hasConstraints, 2);
2357ea844a1aSMatthew Knepley   *hasConstraints = s->bc ? PETSC_TRUE : PETSC_FALSE;
2358ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2359ea844a1aSMatthew Knepley }
2360ea844a1aSMatthew Knepley 
2361ea844a1aSMatthew Knepley /*@C
2362ea844a1aSMatthew Knepley   PetscSectionGetConstraintIndices - Get the point dof numbers, in [0, dof), which are constrained
2363ea844a1aSMatthew Knepley 
236440750d41SVaclav Hapla   Not Collective
2365ea844a1aSMatthew Knepley 
2366ea844a1aSMatthew Knepley   Input Parameters:
2367ea844a1aSMatthew Knepley + s     - The PetscSection
2368ea844a1aSMatthew Knepley - point - The point
2369ea844a1aSMatthew Knepley 
2370ea844a1aSMatthew Knepley   Output Parameter:
2371ea844a1aSMatthew Knepley . indices - The constrained dofs
2372ea844a1aSMatthew Knepley 
2373ea844a1aSMatthew Knepley   Note: In Fortran, you call PetscSectionGetConstraintIndicesF90() and PetscSectionRestoreConstraintIndicesF90()
2374ea844a1aSMatthew Knepley 
2375ea844a1aSMatthew Knepley   Level: intermediate
2376ea844a1aSMatthew Knepley 
2377db781477SPatrick Sanan .seealso: `PetscSectionSetConstraintIndices()`, `PetscSectionGetConstraintDof()`, `PetscSection`
2378ea844a1aSMatthew Knepley @*/
2379*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetConstraintIndices(PetscSection s, PetscInt point, const PetscInt **indices) {
2380ea844a1aSMatthew Knepley   PetscFunctionBegin;
2381ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2382ea844a1aSMatthew Knepley   if (s->bc) {
23839566063dSJacob Faibussowitsch     PetscCall(VecIntGetValuesSection(s->bcIndices, s->bc, point, indices));
2384ea844a1aSMatthew Knepley   } else *indices = NULL;
2385ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2386ea844a1aSMatthew Knepley }
2387ea844a1aSMatthew Knepley 
2388ea844a1aSMatthew Knepley /*@C
2389ea844a1aSMatthew Knepley   PetscSectionSetConstraintIndices - Set the point dof numbers, in [0, dof), which are constrained
2390ea844a1aSMatthew Knepley 
239140750d41SVaclav Hapla   Not Collective
2392ea844a1aSMatthew Knepley 
2393ea844a1aSMatthew Knepley   Input Parameters:
2394ea844a1aSMatthew Knepley + s     - The PetscSection
2395ea844a1aSMatthew Knepley . point - The point
2396ea844a1aSMatthew Knepley - indices - The constrained dofs
2397ea844a1aSMatthew Knepley 
2398ea844a1aSMatthew Knepley   Note: The Fortran is PetscSectionSetConstraintIndicesF90()
2399ea844a1aSMatthew Knepley 
2400ea844a1aSMatthew Knepley   Level: intermediate
2401ea844a1aSMatthew Knepley 
2402db781477SPatrick Sanan .seealso: `PetscSectionGetConstraintIndices()`, `PetscSectionGetConstraintDof()`, `PetscSection`
2403ea844a1aSMatthew Knepley @*/
2404*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetConstraintIndices(PetscSection s, PetscInt point, const PetscInt indices[]) {
2405ea844a1aSMatthew Knepley   PetscFunctionBegin;
2406ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2407ea844a1aSMatthew Knepley   if (s->bc) {
2408d57bb9dbSMatthew G. Knepley     const PetscInt dof  = s->atlasDof[point];
2409d57bb9dbSMatthew G. Knepley     const PetscInt cdof = s->bc->atlasDof[point];
2410d57bb9dbSMatthew G. Knepley     PetscInt       d;
2411d57bb9dbSMatthew G. Knepley 
2412*9371c9d4SSatish Balay     for (d = 0; d < cdof; ++d) { PetscCheck(indices[d] < dof, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %" PetscInt_FMT " dof %" PetscInt_FMT ", invalid constraint index[%" PetscInt_FMT "]: %" PetscInt_FMT, point, dof, d, indices[d]); }
24139566063dSJacob Faibussowitsch     PetscCall(VecIntSetValuesSection(s->bcIndices, s->bc, point, indices, INSERT_VALUES));
2414ea844a1aSMatthew Knepley   }
2415ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2416ea844a1aSMatthew Knepley }
2417ea844a1aSMatthew Knepley 
2418ea844a1aSMatthew Knepley /*@C
2419ea844a1aSMatthew Knepley   PetscSectionGetFieldConstraintIndices - Get the field dof numbers, in [0, fdof), which are constrained
2420ea844a1aSMatthew Knepley 
242140750d41SVaclav Hapla   Not Collective
2422ea844a1aSMatthew Knepley 
2423ea844a1aSMatthew Knepley   Input Parameters:
2424ea844a1aSMatthew Knepley + s     - The PetscSection
2425ea844a1aSMatthew Knepley . field  - The field number
2426ea844a1aSMatthew Knepley - point - The point
2427ea844a1aSMatthew Knepley 
2428ea844a1aSMatthew Knepley   Output Parameter:
24299759eb26SJed Brown . indices - The constrained dofs sorted in ascending order
2430ea844a1aSMatthew Knepley 
24319759eb26SJed Brown   Notes:
24329759eb26SJed Brown   The indices array, which is provided by the caller, must have capacity to hold the number of constrained dofs, e.g., as returned by PetscSectionGetConstraintDof().
24339759eb26SJed Brown 
24349759eb26SJed Brown   Fortran Note:
24359759eb26SJed Brown   In Fortran, you call PetscSectionGetFieldConstraintIndicesF90() and PetscSectionRestoreFieldConstraintIndicesF90()
2436ea844a1aSMatthew Knepley 
2437ea844a1aSMatthew Knepley   Level: intermediate
2438ea844a1aSMatthew Knepley 
2439db781477SPatrick Sanan .seealso: `PetscSectionSetFieldConstraintIndices()`, `PetscSectionGetConstraintIndices()`, `PetscSectionGetConstraintDof()`, `PetscSection`
2440ea844a1aSMatthew Knepley @*/
2441*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldConstraintIndices(PetscSection s, PetscInt point, PetscInt field, const PetscInt **indices) {
2442ea844a1aSMatthew Knepley   PetscFunctionBegin;
2443ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2444dadcf809SJacob Faibussowitsch   PetscValidPointer(indices, 4);
24452abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
24469566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetConstraintIndices(s->field[field], point, indices));
2447ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2448ea844a1aSMatthew Knepley }
2449ea844a1aSMatthew Knepley 
2450ea844a1aSMatthew Knepley /*@C
2451ea844a1aSMatthew Knepley   PetscSectionSetFieldConstraintIndices - Set the field dof numbers, in [0, fdof), which are constrained
2452ea844a1aSMatthew Knepley 
245340750d41SVaclav Hapla   Not Collective
2454ea844a1aSMatthew Knepley 
2455ea844a1aSMatthew Knepley   Input Parameters:
2456ea844a1aSMatthew Knepley + s       - The PetscSection
2457ea844a1aSMatthew Knepley . point   - The point
2458ea844a1aSMatthew Knepley . field   - The field number
2459ea844a1aSMatthew Knepley - indices - The constrained dofs
2460ea844a1aSMatthew Knepley 
2461ea844a1aSMatthew Knepley   Note: The Fortran is PetscSectionSetFieldConstraintIndicesF90()
2462ea844a1aSMatthew Knepley 
2463ea844a1aSMatthew Knepley   Level: intermediate
2464ea844a1aSMatthew Knepley 
2465db781477SPatrick Sanan .seealso: `PetscSectionSetConstraintIndices()`, `PetscSectionGetFieldConstraintIndices()`, `PetscSectionGetConstraintDof()`, `PetscSection`
2466ea844a1aSMatthew Knepley @*/
2467*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldConstraintIndices(PetscSection s, PetscInt point, PetscInt field, const PetscInt indices[]) {
2468ea844a1aSMatthew Knepley   PetscFunctionBegin;
2469ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
24702abc8c78SJacob Faibussowitsch   if (PetscDefined(USE_DEBUG)) {
2471e2bfaee7SMatthew G. Knepley     PetscInt nfdof;
24722abc8c78SJacob Faibussowitsch 
24739566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldConstraintDof(s, point, field, &nfdof));
2474e2bfaee7SMatthew G. Knepley     if (nfdof) PetscValidIntPointer(indices, 4);
24752abc8c78SJacob Faibussowitsch   }
24762abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
24779566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetConstraintIndices(s->field[field], point, indices));
2478ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2479ea844a1aSMatthew Knepley }
2480ea844a1aSMatthew Knepley 
2481ea844a1aSMatthew Knepley /*@
2482ea844a1aSMatthew Knepley   PetscSectionPermute - Reorder the section according to the input point permutation
2483ea844a1aSMatthew Knepley 
248440750d41SVaclav Hapla   Collective
2485ea844a1aSMatthew Knepley 
2486d8d19677SJose E. Roman   Input Parameters:
2487ea844a1aSMatthew Knepley + section - The PetscSection object
2488ea844a1aSMatthew Knepley - perm - The point permutation, old point p becomes new point perm[p]
2489ea844a1aSMatthew Knepley 
2490ea844a1aSMatthew Knepley   Output Parameter:
2491ea844a1aSMatthew Knepley . sectionNew - The permuted PetscSection
2492ea844a1aSMatthew Knepley 
2493ea844a1aSMatthew Knepley   Level: intermediate
2494ea844a1aSMatthew Knepley 
2495db781477SPatrick Sanan .seealso: `MatPermute()`
2496ea844a1aSMatthew Knepley @*/
2497*9371c9d4SSatish Balay PetscErrorCode PetscSectionPermute(PetscSection section, IS permutation, PetscSection *sectionNew) {
2498ea844a1aSMatthew Knepley   PetscSection    s = section, sNew;
2499ea844a1aSMatthew Knepley   const PetscInt *perm;
2500b778fa18SValeria Barra   PetscInt        numFields, f, c, numPoints, pStart, pEnd, p;
2501ea844a1aSMatthew Knepley 
2502ea844a1aSMatthew Knepley   PetscFunctionBegin;
2503ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
2504ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
2505ea844a1aSMatthew Knepley   PetscValidPointer(sectionNew, 3);
25069566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), &sNew));
25079566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetNumFields(s, &numFields));
25089566063dSJacob Faibussowitsch   if (numFields) PetscCall(PetscSectionSetNumFields(sNew, numFields));
2509ea844a1aSMatthew Knepley   for (f = 0; f < numFields; ++f) {
2510ea844a1aSMatthew Knepley     const char *name;
2511ea844a1aSMatthew Knepley     PetscInt    numComp;
2512ea844a1aSMatthew Knepley 
25139566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldName(s, f, &name));
25149566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldName(sNew, f, name));
25159566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetFieldComponents(s, f, &numComp));
25169566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldComponents(sNew, f, numComp));
2517b778fa18SValeria Barra     for (c = 0; c < s->numFieldComponents[f]; ++c) {
25189566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetComponentName(s, f, c, &name));
25199566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetComponentName(sNew, f, c, name));
2520b778fa18SValeria Barra     }
2521ea844a1aSMatthew Knepley   }
25229566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(permutation, &numPoints));
25239566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(permutation, &perm));
25249566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
25259566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(sNew, pStart, pEnd));
252608401ef6SPierre Jolivet   PetscCheck(numPoints >= pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Permutation size %" PetscInt_FMT " is less than largest Section point %" PetscInt_FMT, numPoints, pEnd);
2527ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
2528ea844a1aSMatthew Knepley     PetscInt dof, cdof;
2529ea844a1aSMatthew Knepley 
25309566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(s, p, &dof));
25319566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(sNew, perm[p], dof));
25329566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
25339566063dSJacob Faibussowitsch     if (cdof) PetscCall(PetscSectionSetConstraintDof(sNew, perm[p], cdof));
2534ea844a1aSMatthew Knepley     for (f = 0; f < numFields; ++f) {
25359566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldDof(s, p, f, &dof));
25369566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetFieldDof(sNew, perm[p], f, dof));
25379566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &cdof));
25389566063dSJacob Faibussowitsch       if (cdof) PetscCall(PetscSectionSetFieldConstraintDof(sNew, perm[p], f, cdof));
2539ea844a1aSMatthew Knepley     }
2540ea844a1aSMatthew Knepley   }
25419566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(sNew));
2542ea844a1aSMatthew Knepley   for (p = pStart; p < pEnd; ++p) {
2543ea844a1aSMatthew Knepley     const PetscInt *cind;
2544ea844a1aSMatthew Knepley     PetscInt        cdof;
2545ea844a1aSMatthew Knepley 
25469566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
2547ea844a1aSMatthew Knepley     if (cdof) {
25489566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetConstraintIndices(s, p, &cind));
25499566063dSJacob Faibussowitsch       PetscCall(PetscSectionSetConstraintIndices(sNew, perm[p], cind));
2550ea844a1aSMatthew Knepley     }
2551ea844a1aSMatthew Knepley     for (f = 0; f < numFields; ++f) {
25529566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &cdof));
2553ea844a1aSMatthew Knepley       if (cdof) {
25549566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldConstraintIndices(s, p, f, &cind));
25559566063dSJacob Faibussowitsch         PetscCall(PetscSectionSetFieldConstraintIndices(sNew, perm[p], f, cind));
2556ea844a1aSMatthew Knepley       }
2557ea844a1aSMatthew Knepley     }
2558ea844a1aSMatthew Knepley   }
25599566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(permutation, &perm));
2560ea844a1aSMatthew Knepley   *sectionNew = sNew;
2561ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2562ea844a1aSMatthew Knepley }
2563ea844a1aSMatthew Knepley 
2564ea844a1aSMatthew Knepley /*@
2565ea844a1aSMatthew Knepley   PetscSectionSetClosureIndex - Set a cache of points in the closure of each point in the section
2566ea844a1aSMatthew Knepley 
256740750d41SVaclav Hapla   Collective
2568ea844a1aSMatthew Knepley 
2569ea844a1aSMatthew Knepley   Input Parameters:
2570ea844a1aSMatthew Knepley + section   - The PetscSection
2571ea844a1aSMatthew Knepley . obj       - A PetscObject which serves as the key for this index
2572ea844a1aSMatthew Knepley . clSection - Section giving the size of the closure of each point
2573ea844a1aSMatthew Knepley - clPoints  - IS giving the points in each closure
2574ea844a1aSMatthew Knepley 
2575ea844a1aSMatthew Knepley   Note: We compress out closure points with no dofs in this section
2576ea844a1aSMatthew Knepley 
2577ea844a1aSMatthew Knepley   Level: advanced
2578ea844a1aSMatthew Knepley 
2579db781477SPatrick Sanan .seealso: `PetscSectionGetClosureIndex()`, `DMPlexCreateClosureIndex()`
2580ea844a1aSMatthew Knepley @*/
2581*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetClosureIndex(PetscSection section, PetscObject obj, PetscSection clSection, IS clPoints) {
2582ea844a1aSMatthew Knepley   PetscFunctionBegin;
25833e03ebd8SStefano Zampini   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
25843e03ebd8SStefano Zampini   PetscValidHeaderSpecific(clSection, PETSC_SECTION_CLASSID, 3);
25853e03ebd8SStefano Zampini   PetscValidHeaderSpecific(clPoints, IS_CLASSID, 4);
25869566063dSJacob Faibussowitsch   if (section->clObj != obj) PetscCall(PetscSectionResetClosurePermutation(section));
2587ea844a1aSMatthew Knepley   section->clObj = obj;
25889566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)clSection));
25899566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)clPoints));
25909566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&section->clSection));
25919566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&section->clPoints));
2592ea844a1aSMatthew Knepley   section->clSection = clSection;
2593ea844a1aSMatthew Knepley   section->clPoints  = clPoints;
2594ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2595ea844a1aSMatthew Knepley }
2596ea844a1aSMatthew Knepley 
2597ea844a1aSMatthew Knepley /*@
2598ea844a1aSMatthew Knepley   PetscSectionGetClosureIndex - Get the cache of points in the closure of each point in the section
2599ea844a1aSMatthew Knepley 
260040750d41SVaclav Hapla   Collective
2601ea844a1aSMatthew Knepley 
2602ea844a1aSMatthew Knepley   Input Parameters:
2603ea844a1aSMatthew Knepley + section   - The PetscSection
2604ea844a1aSMatthew Knepley - obj       - A PetscObject which serves as the key for this index
2605ea844a1aSMatthew Knepley 
2606ea844a1aSMatthew Knepley   Output Parameters:
2607ea844a1aSMatthew Knepley + clSection - Section giving the size of the closure of each point
2608ea844a1aSMatthew Knepley - clPoints  - IS giving the points in each closure
2609ea844a1aSMatthew Knepley 
2610ea844a1aSMatthew Knepley   Note: We compress out closure points with no dofs in this section
2611ea844a1aSMatthew Knepley 
2612ea844a1aSMatthew Knepley   Level: advanced
2613ea844a1aSMatthew Knepley 
2614db781477SPatrick Sanan .seealso: `PetscSectionSetClosureIndex()`, `DMPlexCreateClosureIndex()`
2615ea844a1aSMatthew Knepley @*/
2616*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetClosureIndex(PetscSection section, PetscObject obj, PetscSection *clSection, IS *clPoints) {
2617ea844a1aSMatthew Knepley   PetscFunctionBegin;
2618ea844a1aSMatthew Knepley   if (section->clObj == obj) {
2619ea844a1aSMatthew Knepley     if (clSection) *clSection = section->clSection;
2620ea844a1aSMatthew Knepley     if (clPoints) *clPoints = section->clPoints;
2621ea844a1aSMatthew Knepley   } else {
2622ea844a1aSMatthew Knepley     if (clSection) *clSection = NULL;
2623ea844a1aSMatthew Knepley     if (clPoints) *clPoints = NULL;
2624ea844a1aSMatthew Knepley   }
2625ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2626ea844a1aSMatthew Knepley }
2627ea844a1aSMatthew Knepley 
2628*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetClosurePermutation_Internal(PetscSection section, PetscObject obj, PetscInt depth, PetscInt clSize, PetscCopyMode mode, PetscInt *clPerm) {
2629ea844a1aSMatthew Knepley   PetscInt                    i;
2630c459fbc1SJed Brown   khiter_t                    iter;
2631c459fbc1SJed Brown   int                         new_entry;
2632c459fbc1SJed Brown   PetscSectionClosurePermKey  key = {depth, clSize};
2633c459fbc1SJed Brown   PetscSectionClosurePermVal *val;
2634ea844a1aSMatthew Knepley 
2635ea844a1aSMatthew Knepley   PetscFunctionBegin;
2636ea844a1aSMatthew Knepley   if (section->clObj != obj) {
26379566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&section->clSection));
26389566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&section->clPoints));
2639ea844a1aSMatthew Knepley   }
2640ea844a1aSMatthew Knepley   section->clObj = obj;
26419566063dSJacob Faibussowitsch   if (!section->clHash) PetscCall(PetscClPermCreate(&section->clHash));
2642c459fbc1SJed Brown   iter = kh_put(ClPerm, section->clHash, key, &new_entry);
2643c459fbc1SJed Brown   val  = &kh_val(section->clHash, iter);
2644c459fbc1SJed Brown   if (!new_entry) {
26459566063dSJacob Faibussowitsch     PetscCall(PetscFree(val->perm));
26469566063dSJacob Faibussowitsch     PetscCall(PetscFree(val->invPerm));
2647c459fbc1SJed Brown   }
2648ea844a1aSMatthew Knepley   if (mode == PETSC_COPY_VALUES) {
26499566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(clSize, &val->perm));
26509566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)obj, clSize * sizeof(PetscInt)));
26519566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(val->perm, clPerm, clSize));
2652ea844a1aSMatthew Knepley   } else if (mode == PETSC_OWN_POINTER) {
2653c459fbc1SJed Brown     val->perm = clPerm;
2654ea844a1aSMatthew Knepley   } else SETERRQ(PetscObjectComm(obj), PETSC_ERR_SUP, "Do not support borrowed arrays");
26559566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(clSize, &val->invPerm));
2656c459fbc1SJed Brown   for (i = 0; i < clSize; ++i) val->invPerm[clPerm[i]] = i;
2657ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2658ea844a1aSMatthew Knepley }
2659ea844a1aSMatthew Knepley 
2660ea844a1aSMatthew Knepley /*@
2661c459fbc1SJed Brown   PetscSectionSetClosurePermutation - Set the dof permutation for the closure of each cell in the section, meaning clPerm[newIndex] = oldIndex.
2662ea844a1aSMatthew Knepley 
2663ea844a1aSMatthew Knepley   Not Collective
2664ea844a1aSMatthew Knepley 
2665ea844a1aSMatthew Knepley   Input Parameters:
2666ea844a1aSMatthew Knepley + section - The PetscSection
2667c459fbc1SJed Brown . obj     - A PetscObject which serves as the key for this index (usually a DM)
2668c459fbc1SJed Brown . depth   - Depth of points on which to apply the given permutation
2669ea844a1aSMatthew Knepley - perm    - Permutation of the cell dof closure
2670ea844a1aSMatthew Knepley 
2671c459fbc1SJed Brown   Note:
2672c459fbc1SJed Brown   The specified permutation will only be applied to points at depth whose closure size matches the length of perm.  In a
2673c459fbc1SJed Brown   mixed-topology or variable-degree finite element space, this function can be called multiple times at each depth for
2674c459fbc1SJed Brown   each topology and degree.
2675c459fbc1SJed Brown 
2676c459fbc1SJed Brown   This approach assumes that (depth, len(perm)) uniquely identifies the desired permutation; this might not be true for
2677c459fbc1SJed Brown   exotic/enriched spaces on mixed topology meshes.
2678ea844a1aSMatthew Knepley 
2679ea844a1aSMatthew Knepley   Level: intermediate
2680ea844a1aSMatthew Knepley 
2681db781477SPatrick Sanan .seealso: `PetscSectionGetClosurePermutation()`, `PetscSectionGetClosureIndex()`, `DMPlexCreateClosureIndex()`, `PetscCopyMode`
2682ea844a1aSMatthew Knepley @*/
2683*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetClosurePermutation(PetscSection section, PetscObject obj, PetscInt depth, IS perm) {
2684ea844a1aSMatthew Knepley   const PetscInt *clPerm = NULL;
2685ea844a1aSMatthew Knepley   PetscInt        clSize = 0;
2686ea844a1aSMatthew Knepley 
2687ea844a1aSMatthew Knepley   PetscFunctionBegin;
2688ea844a1aSMatthew Knepley   if (perm) {
26899566063dSJacob Faibussowitsch     PetscCall(ISGetLocalSize(perm, &clSize));
26909566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(perm, &clPerm));
2691ea844a1aSMatthew Knepley   }
26929566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetClosurePermutation_Internal(section, obj, depth, clSize, PETSC_COPY_VALUES, (PetscInt *)clPerm));
26939566063dSJacob Faibussowitsch   if (perm) PetscCall(ISRestoreIndices(perm, &clPerm));
2694ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2695ea844a1aSMatthew Knepley }
2696ea844a1aSMatthew Knepley 
2697*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetClosurePermutation_Internal(PetscSection section, PetscObject obj, PetscInt depth, PetscInt size, const PetscInt *perm[]) {
2698ea844a1aSMatthew Knepley   PetscFunctionBegin;
2699ea844a1aSMatthew Knepley   if (section->clObj == obj) {
2700c459fbc1SJed Brown     PetscSectionClosurePermKey k = {depth, size};
2701c459fbc1SJed Brown     PetscSectionClosurePermVal v;
27029566063dSJacob Faibussowitsch     PetscCall(PetscClPermGet(section->clHash, k, &v));
2703c459fbc1SJed Brown     if (perm) *perm = v.perm;
2704ea844a1aSMatthew Knepley   } else {
2705ea844a1aSMatthew Knepley     if (perm) *perm = NULL;
2706ea844a1aSMatthew Knepley   }
2707ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2708ea844a1aSMatthew Knepley }
2709ea844a1aSMatthew Knepley 
2710ea844a1aSMatthew Knepley /*@
2711ea844a1aSMatthew Knepley   PetscSectionGetClosurePermutation - Get the dof permutation for the closure of each cell in the section, meaning clPerm[newIndex] = oldIndex.
2712ea844a1aSMatthew Knepley 
271340750d41SVaclav Hapla   Not Collective
2714ea844a1aSMatthew Knepley 
2715ea844a1aSMatthew Knepley   Input Parameters:
2716ea844a1aSMatthew Knepley + section   - The PetscSection
2717c459fbc1SJed Brown . obj       - A PetscObject which serves as the key for this index (usually a DM)
2718c459fbc1SJed Brown . depth     - Depth stratum on which to obtain closure permutation
2719c459fbc1SJed Brown - clSize    - Closure size to be permuted (e.g., may vary with element topology and degree)
2720ea844a1aSMatthew Knepley 
2721ea844a1aSMatthew Knepley   Output Parameter:
2722ea844a1aSMatthew Knepley . perm - The dof closure permutation
2723ea844a1aSMatthew Knepley 
2724c459fbc1SJed Brown   Note:
2725ea844a1aSMatthew Knepley   The user must destroy the IS that is returned.
2726ea844a1aSMatthew Knepley 
2727ea844a1aSMatthew Knepley   Level: intermediate
2728ea844a1aSMatthew Knepley 
2729db781477SPatrick Sanan .seealso: `PetscSectionSetClosurePermutation()`, `PetscSectionGetClosureInversePermutation()`, `PetscSectionGetClosureIndex()`, `PetscSectionSetClosureIndex()`, `DMPlexCreateClosureIndex()`
2730ea844a1aSMatthew Knepley @*/
2731*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetClosurePermutation(PetscSection section, PetscObject obj, PetscInt depth, PetscInt clSize, IS *perm) {
2732ea844a1aSMatthew Knepley   const PetscInt *clPerm;
2733ea844a1aSMatthew Knepley 
2734ea844a1aSMatthew Knepley   PetscFunctionBegin;
27359566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetClosurePermutation_Internal(section, obj, depth, clSize, &clPerm));
27369566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, clSize, clPerm, PETSC_USE_POINTER, perm));
2737ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2738ea844a1aSMatthew Knepley }
2739ea844a1aSMatthew Knepley 
2740*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetClosureInversePermutation_Internal(PetscSection section, PetscObject obj, PetscInt depth, PetscInt size, const PetscInt *perm[]) {
2741ea844a1aSMatthew Knepley   PetscFunctionBegin;
2742c459fbc1SJed Brown   if (section->clObj == obj && section->clHash) {
2743c459fbc1SJed Brown     PetscSectionClosurePermKey k = {depth, size};
2744c459fbc1SJed Brown     PetscSectionClosurePermVal v;
27459566063dSJacob Faibussowitsch     PetscCall(PetscClPermGet(section->clHash, k, &v));
2746c459fbc1SJed Brown     if (perm) *perm = v.invPerm;
2747ea844a1aSMatthew Knepley   } else {
2748ea844a1aSMatthew Knepley     if (perm) *perm = NULL;
2749ea844a1aSMatthew Knepley   }
2750ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2751ea844a1aSMatthew Knepley }
2752ea844a1aSMatthew Knepley 
2753ea844a1aSMatthew Knepley /*@
2754ea844a1aSMatthew Knepley   PetscSectionGetClosureInversePermutation - Get the inverse dof permutation for the closure of each cell in the section, meaning clPerm[oldIndex] = newIndex.
2755ea844a1aSMatthew Knepley 
275640750d41SVaclav Hapla   Not Collective
2757ea844a1aSMatthew Knepley 
2758ea844a1aSMatthew Knepley   Input Parameters:
2759ea844a1aSMatthew Knepley + section   - The PetscSection
2760c459fbc1SJed Brown . obj       - A PetscObject which serves as the key for this index (usually a DM)
2761c459fbc1SJed Brown . depth     - Depth stratum on which to obtain closure permutation
2762c459fbc1SJed Brown - clSize    - Closure size to be permuted (e.g., may vary with element topology and degree)
2763ea844a1aSMatthew Knepley 
2764ea844a1aSMatthew Knepley   Output Parameters:
2765c459fbc1SJed Brown . perm - The dof closure permutation
2766ea844a1aSMatthew Knepley 
2767c459fbc1SJed Brown   Note:
2768ea844a1aSMatthew Knepley   The user must destroy the IS that is returned.
2769ea844a1aSMatthew Knepley 
2770ea844a1aSMatthew Knepley   Level: intermediate
2771ea844a1aSMatthew Knepley 
2772db781477SPatrick Sanan .seealso: `PetscSectionSetClosurePermutation()`, `PetscSectionGetClosureIndex()`, `PetscSectionSetClosureIndex()`, `DMPlexCreateClosureIndex()`
2773ea844a1aSMatthew Knepley @*/
2774*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetClosureInversePermutation(PetscSection section, PetscObject obj, PetscInt depth, PetscInt clSize, IS *perm) {
2775ea844a1aSMatthew Knepley   const PetscInt *clPerm;
2776ea844a1aSMatthew Knepley 
2777ea844a1aSMatthew Knepley   PetscFunctionBegin;
27789566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetClosureInversePermutation_Internal(section, obj, depth, clSize, &clPerm));
27799566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, clSize, clPerm, PETSC_USE_POINTER, perm));
2780ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2781ea844a1aSMatthew Knepley }
2782ea844a1aSMatthew Knepley 
2783ea844a1aSMatthew Knepley /*@
2784ea844a1aSMatthew Knepley   PetscSectionGetField - Get the subsection associated with a single field
2785ea844a1aSMatthew Knepley 
2786ea844a1aSMatthew Knepley   Input Parameters:
2787ea844a1aSMatthew Knepley + s     - The PetscSection
2788ea844a1aSMatthew Knepley - field - The field number
2789ea844a1aSMatthew Knepley 
2790ea844a1aSMatthew Knepley   Output Parameter:
2791ea844a1aSMatthew Knepley . subs  - The subsection for the given field
2792ea844a1aSMatthew Knepley 
2793ea844a1aSMatthew Knepley   Level: intermediate
2794ea844a1aSMatthew Knepley 
2795db781477SPatrick Sanan .seealso: `PetscSectionSetNumFields()`
2796ea844a1aSMatthew Knepley @*/
2797*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetField(PetscSection s, PetscInt field, PetscSection *subs) {
2798ea844a1aSMatthew Knepley   PetscFunctionBegin;
2799ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2800ea844a1aSMatthew Knepley   PetscValidPointer(subs, 3);
28012abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, s->numFields);
2802ea844a1aSMatthew Knepley   *subs = s->field[field];
2803ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2804ea844a1aSMatthew Knepley }
2805ea844a1aSMatthew Knepley 
2806ea844a1aSMatthew Knepley PetscClassId      PETSC_SECTION_SYM_CLASSID;
2807ea844a1aSMatthew Knepley PetscFunctionList PetscSectionSymList = NULL;
2808ea844a1aSMatthew Knepley 
2809ea844a1aSMatthew Knepley /*@
2810ea844a1aSMatthew Knepley   PetscSectionSymCreate - Creates an empty PetscSectionSym object.
2811ea844a1aSMatthew Knepley 
2812ea844a1aSMatthew Knepley   Collective
2813ea844a1aSMatthew Knepley 
2814ea844a1aSMatthew Knepley   Input Parameter:
2815ea844a1aSMatthew Knepley . comm - the MPI communicator
2816ea844a1aSMatthew Knepley 
2817ea844a1aSMatthew Knepley   Output Parameter:
2818ea844a1aSMatthew Knepley . sym - pointer to the new set of symmetries
2819ea844a1aSMatthew Knepley 
2820ea844a1aSMatthew Knepley   Level: developer
2821ea844a1aSMatthew Knepley 
2822db781477SPatrick Sanan .seealso: `PetscSectionSym`, `PetscSectionSymDestroy()`
2823ea844a1aSMatthew Knepley @*/
2824*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymCreate(MPI_Comm comm, PetscSectionSym *sym) {
2825ea844a1aSMatthew Knepley   PetscFunctionBegin;
2826ea844a1aSMatthew Knepley   PetscValidPointer(sym, 2);
28279566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
28289566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*sym, PETSC_SECTION_SYM_CLASSID, "PetscSectionSym", "Section Symmetry", "IS", comm, PetscSectionSymDestroy, PetscSectionSymView));
2829ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2830ea844a1aSMatthew Knepley }
2831ea844a1aSMatthew Knepley 
2832ea844a1aSMatthew Knepley /*@C
2833ea844a1aSMatthew Knepley   PetscSectionSymSetType - Builds a PetscSection symmetry, for a particular implementation.
2834ea844a1aSMatthew Knepley 
283540750d41SVaclav Hapla   Collective
2836ea844a1aSMatthew Knepley 
2837ea844a1aSMatthew Knepley   Input Parameters:
2838ea844a1aSMatthew Knepley + sym    - The section symmetry object
2839ea844a1aSMatthew Knepley - method - The name of the section symmetry type
2840ea844a1aSMatthew Knepley 
2841ea844a1aSMatthew Knepley   Level: developer
2842ea844a1aSMatthew Knepley 
2843db781477SPatrick Sanan .seealso: `PetscSectionSymGetType()`, `PetscSectionSymCreate()`
2844ea844a1aSMatthew Knepley @*/
2845*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymSetType(PetscSectionSym sym, PetscSectionSymType method) {
2846ea844a1aSMatthew Knepley   PetscErrorCode (*r)(PetscSectionSym);
2847ea844a1aSMatthew Knepley   PetscBool match;
2848ea844a1aSMatthew Knepley 
2849ea844a1aSMatthew Knepley   PetscFunctionBegin;
2850ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
28519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)sym, method, &match));
2852ea844a1aSMatthew Knepley   if (match) PetscFunctionReturn(0);
2853ea844a1aSMatthew Knepley 
28549566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscSectionSymList, method, &r));
285528b400f6SJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSectionSym type: %s", method);
2856dbbe0bcdSBarry Smith   PetscTryTypeMethod(sym, destroy);
2857ea844a1aSMatthew Knepley   sym->ops->destroy = NULL;
2858dbbe0bcdSBarry Smith 
28599566063dSJacob Faibussowitsch   PetscCall((*r)(sym));
28609566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)sym, method));
2861ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2862ea844a1aSMatthew Knepley }
2863ea844a1aSMatthew Knepley 
2864ea844a1aSMatthew Knepley /*@C
2865ea844a1aSMatthew Knepley   PetscSectionSymGetType - Gets the section symmetry type name (as a string) from the PetscSectionSym.
2866ea844a1aSMatthew Knepley 
2867ea844a1aSMatthew Knepley   Not Collective
2868ea844a1aSMatthew Knepley 
2869ea844a1aSMatthew Knepley   Input Parameter:
2870ea844a1aSMatthew Knepley . sym  - The section symmetry
2871ea844a1aSMatthew Knepley 
2872ea844a1aSMatthew Knepley   Output Parameter:
2873ea844a1aSMatthew Knepley . type - The index set type name
2874ea844a1aSMatthew Knepley 
2875ea844a1aSMatthew Knepley   Level: developer
2876ea844a1aSMatthew Knepley 
2877db781477SPatrick Sanan .seealso: `PetscSectionSymSetType()`, `PetscSectionSymCreate()`
2878ea844a1aSMatthew Knepley @*/
2879*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymGetType(PetscSectionSym sym, PetscSectionSymType *type) {
2880ea844a1aSMatthew Knepley   PetscFunctionBegin;
2881ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
2882dadcf809SJacob Faibussowitsch   PetscValidPointer(type, 2);
2883ea844a1aSMatthew Knepley   *type = ((PetscObject)sym)->type_name;
2884ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2885ea844a1aSMatthew Knepley }
2886ea844a1aSMatthew Knepley 
2887ea844a1aSMatthew Knepley /*@C
2888ea844a1aSMatthew Knepley   PetscSectionSymRegister - Adds a new section symmetry implementation
2889ea844a1aSMatthew Knepley 
2890ea844a1aSMatthew Knepley   Not Collective
2891ea844a1aSMatthew Knepley 
2892ea844a1aSMatthew Knepley   Input Parameters:
2893ea844a1aSMatthew Knepley + name        - The name of a new user-defined creation routine
2894ea844a1aSMatthew Knepley - create_func - The creation routine itself
2895ea844a1aSMatthew Knepley 
2896ea844a1aSMatthew Knepley   Notes:
2897ea844a1aSMatthew Knepley   PetscSectionSymRegister() may be called multiple times to add several user-defined vectors
2898ea844a1aSMatthew Knepley 
2899ea844a1aSMatthew Knepley   Level: developer
2900ea844a1aSMatthew Knepley 
2901db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSymSetType()`
2902ea844a1aSMatthew Knepley @*/
2903*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymRegister(const char sname[], PetscErrorCode (*function)(PetscSectionSym)) {
2904ea844a1aSMatthew Knepley   PetscFunctionBegin;
29059566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
29069566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscSectionSymList, sname, function));
2907ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2908ea844a1aSMatthew Knepley }
2909ea844a1aSMatthew Knepley 
2910ea844a1aSMatthew Knepley /*@
2911ea844a1aSMatthew Knepley    PetscSectionSymDestroy - Destroys a section symmetry.
2912ea844a1aSMatthew Knepley 
291340750d41SVaclav Hapla    Collective
2914ea844a1aSMatthew Knepley 
2915ea844a1aSMatthew Knepley    Input Parameters:
2916ea844a1aSMatthew Knepley .  sym - the section symmetry
2917ea844a1aSMatthew Knepley 
2918ea844a1aSMatthew Knepley    Level: developer
2919ea844a1aSMatthew Knepley 
2920db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSymDestroy()`
2921ea844a1aSMatthew Knepley @*/
2922*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymDestroy(PetscSectionSym *sym) {
2923ea844a1aSMatthew Knepley   SymWorkLink link, next;
2924ea844a1aSMatthew Knepley 
2925ea844a1aSMatthew Knepley   PetscFunctionBegin;
2926ea844a1aSMatthew Knepley   if (!*sym) PetscFunctionReturn(0);
2927ea844a1aSMatthew Knepley   PetscValidHeaderSpecific((*sym), PETSC_SECTION_SYM_CLASSID, 1);
2928*9371c9d4SSatish Balay   if (--((PetscObject)(*sym))->refct > 0) {
2929*9371c9d4SSatish Balay     *sym = NULL;
2930*9371c9d4SSatish Balay     PetscFunctionReturn(0);
2931ea844a1aSMatthew Knepley   }
2932*9371c9d4SSatish Balay   if ((*sym)->ops->destroy) { PetscCall((*(*sym)->ops->destroy)(*sym)); }
2933c9cc58a2SBarry Smith   PetscCheck(!(*sym)->workout, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Work array still checked out");
2934ea844a1aSMatthew Knepley   for (link = (*sym)->workin; link; link = next) {
29350c99d500SBarry Smith     PetscInt    **perms = (PetscInt **)link->perms;
29360c99d500SBarry Smith     PetscScalar **rots  = (PetscScalar **)link->rots;
29370c99d500SBarry Smith     PetscCall(PetscFree2(perms, rots));
2938ea844a1aSMatthew Knepley     next = link->next;
29399566063dSJacob Faibussowitsch     PetscCall(PetscFree(link));
2940ea844a1aSMatthew Knepley   }
2941ea844a1aSMatthew Knepley   (*sym)->workin = NULL;
29429566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(sym));
2943ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2944ea844a1aSMatthew Knepley }
2945ea844a1aSMatthew Knepley 
2946ea844a1aSMatthew Knepley /*@C
2947ea844a1aSMatthew Knepley    PetscSectionSymView - Displays a section symmetry
2948ea844a1aSMatthew Knepley 
294940750d41SVaclav Hapla    Collective
2950ea844a1aSMatthew Knepley 
2951ea844a1aSMatthew Knepley    Input Parameters:
2952ea844a1aSMatthew Knepley +  sym - the index set
2953ea844a1aSMatthew Knepley -  viewer - viewer used to display the set, for example PETSC_VIEWER_STDOUT_SELF.
2954ea844a1aSMatthew Knepley 
2955ea844a1aSMatthew Knepley    Level: developer
2956ea844a1aSMatthew Knepley 
2957db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`
2958ea844a1aSMatthew Knepley @*/
2959*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymView(PetscSectionSym sym, PetscViewer viewer) {
2960ea844a1aSMatthew Knepley   PetscFunctionBegin;
2961ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
2962*9371c9d4SSatish Balay   if (!viewer) { PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sym), &viewer)); }
2963ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2964ea844a1aSMatthew Knepley   PetscCheckSameComm(sym, 1, viewer, 2);
29659566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sym, viewer));
2966dbbe0bcdSBarry Smith   PetscTryTypeMethod(sym, view, viewer);
2967ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2968ea844a1aSMatthew Knepley }
2969ea844a1aSMatthew Knepley 
2970ea844a1aSMatthew Knepley /*@
2971ea844a1aSMatthew Knepley   PetscSectionSetSym - Set the symmetries for the data referred to by the section
2972ea844a1aSMatthew Knepley 
297340750d41SVaclav Hapla   Collective
2974ea844a1aSMatthew Knepley 
2975ea844a1aSMatthew Knepley   Input Parameters:
2976ea844a1aSMatthew Knepley + section - the section describing data layout
2977ea844a1aSMatthew Knepley - sym - the symmetry describing the affect of orientation on the access of the data
2978ea844a1aSMatthew Knepley 
2979ea844a1aSMatthew Knepley   Level: developer
2980ea844a1aSMatthew Knepley 
2981db781477SPatrick Sanan .seealso: `PetscSectionGetSym()`, `PetscSectionSymCreate()`
2982ea844a1aSMatthew Knepley @*/
2983*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetSym(PetscSection section, PetscSectionSym sym) {
2984ea844a1aSMatthew Knepley   PetscFunctionBegin;
2985ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
29869566063dSJacob Faibussowitsch   PetscCall(PetscSectionSymDestroy(&(section->sym)));
2987ea844a1aSMatthew Knepley   if (sym) {
2988ea844a1aSMatthew Knepley     PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 2);
2989ea844a1aSMatthew Knepley     PetscCheckSameComm(section, 1, sym, 2);
29909566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)sym));
2991ea844a1aSMatthew Knepley   }
2992ea844a1aSMatthew Knepley   section->sym = sym;
2993ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
2994ea844a1aSMatthew Knepley }
2995ea844a1aSMatthew Knepley 
2996ea844a1aSMatthew Knepley /*@
2997ea844a1aSMatthew Knepley   PetscSectionGetSym - Get the symmetries for the data referred to by the section
2998ea844a1aSMatthew Knepley 
299940750d41SVaclav Hapla   Not Collective
3000ea844a1aSMatthew Knepley 
3001ea844a1aSMatthew Knepley   Input Parameters:
3002ea844a1aSMatthew Knepley . section - the section describing data layout
3003ea844a1aSMatthew Knepley 
3004ea844a1aSMatthew Knepley   Output Parameters:
3005ea844a1aSMatthew Knepley . sym - the symmetry describing the affect of orientation on the access of the data
3006ea844a1aSMatthew Knepley 
3007ea844a1aSMatthew Knepley   Level: developer
3008ea844a1aSMatthew Knepley 
3009db781477SPatrick Sanan .seealso: `PetscSectionSetSym()`, `PetscSectionSymCreate()`
3010ea844a1aSMatthew Knepley @*/
3011*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetSym(PetscSection section, PetscSectionSym *sym) {
3012ea844a1aSMatthew Knepley   PetscFunctionBegin;
3013ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
3014ea844a1aSMatthew Knepley   *sym = section->sym;
3015ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3016ea844a1aSMatthew Knepley }
3017ea844a1aSMatthew Knepley 
3018ea844a1aSMatthew Knepley /*@
3019ea844a1aSMatthew Knepley   PetscSectionSetFieldSym - Set the symmetries for the data referred to by a field of the section
3020ea844a1aSMatthew Knepley 
302140750d41SVaclav Hapla   Collective
3022ea844a1aSMatthew Knepley 
3023ea844a1aSMatthew Knepley   Input Parameters:
3024ea844a1aSMatthew Knepley + section - the section describing data layout
3025ea844a1aSMatthew Knepley . field - the field number
3026ea844a1aSMatthew Knepley - sym - the symmetry describing the affect of orientation on the access of the data
3027ea844a1aSMatthew Knepley 
3028ea844a1aSMatthew Knepley   Level: developer
3029ea844a1aSMatthew Knepley 
3030db781477SPatrick Sanan .seealso: `PetscSectionGetFieldSym()`, `PetscSectionSymCreate()`
3031ea844a1aSMatthew Knepley @*/
3032*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetFieldSym(PetscSection section, PetscInt field, PetscSectionSym sym) {
3033ea844a1aSMatthew Knepley   PetscFunctionBegin;
3034ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
30352abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, section->numFields);
30369566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetSym(section->field[field], sym));
3037ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3038ea844a1aSMatthew Knepley }
3039ea844a1aSMatthew Knepley 
3040ea844a1aSMatthew Knepley /*@
3041ea844a1aSMatthew Knepley   PetscSectionGetFieldSym - Get the symmetries for the data referred to by a field of the section
3042ea844a1aSMatthew Knepley 
304340750d41SVaclav Hapla   Collective
3044ea844a1aSMatthew Knepley 
3045ea844a1aSMatthew Knepley   Input Parameters:
3046ea844a1aSMatthew Knepley + section - the section describing data layout
3047ea844a1aSMatthew Knepley - field - the field number
3048ea844a1aSMatthew Knepley 
3049ea844a1aSMatthew Knepley   Output Parameters:
3050ea844a1aSMatthew Knepley . sym - the symmetry describing the affect of orientation on the access of the data
3051ea844a1aSMatthew Knepley 
3052ea844a1aSMatthew Knepley   Level: developer
3053ea844a1aSMatthew Knepley 
3054db781477SPatrick Sanan .seealso: `PetscSectionSetFieldSym()`, `PetscSectionSymCreate()`
3055ea844a1aSMatthew Knepley @*/
3056*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldSym(PetscSection section, PetscInt field, PetscSectionSym *sym) {
3057ea844a1aSMatthew Knepley   PetscFunctionBegin;
3058ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
30592abc8c78SJacob Faibussowitsch   PetscSectionCheckValidField(field, section->numFields);
3060ea844a1aSMatthew Knepley   *sym = section->field[field]->sym;
3061ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3062ea844a1aSMatthew Knepley }
3063ea844a1aSMatthew Knepley 
3064ea844a1aSMatthew Knepley /*@C
3065ea844a1aSMatthew Knepley   PetscSectionGetPointSyms - Get the symmetries for a set of points in a PetscSection under specific orientations.
3066ea844a1aSMatthew Knepley 
306740750d41SVaclav Hapla   Not Collective
3068ea844a1aSMatthew Knepley 
3069ea844a1aSMatthew Knepley   Input Parameters:
3070ea844a1aSMatthew Knepley + section - the section
3071ea844a1aSMatthew Knepley . numPoints - the number of points
3072ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an
3073ea844a1aSMatthew Knepley     arbitrary integer: its interpretation is up to sym.  Orientations are used by DM: for their interpretation in that
3074ea844a1aSMatthew Knepley     context, see DMPlexGetConeOrientation()).
3075ea844a1aSMatthew Knepley 
3076d8d19677SJose E. Roman   Output Parameters:
3077ea844a1aSMatthew Knepley + perms - The permutations for the given orientations (or NULL if there is no symmetry or the permutation is the identity).
3078ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations (or NULL if there is no symmetry or the rotations are all
3079ea844a1aSMatthew Knepley     identity).
3080ea844a1aSMatthew Knepley 
3081ea844a1aSMatthew Knepley   Example of usage, gathering dofs into a local array (lArray) from a section array (sArray):
3082ea844a1aSMatthew Knepley .vb
3083ea844a1aSMatthew Knepley      const PetscInt    **perms;
3084ea844a1aSMatthew Knepley      const PetscScalar **rots;
3085ea844a1aSMatthew Knepley      PetscInt            lOffset;
3086ea844a1aSMatthew Knepley 
3087ea844a1aSMatthew Knepley      PetscSectionGetPointSyms(section,numPoints,points,&perms,&rots);
3088ea844a1aSMatthew Knepley      for (i = 0, lOffset = 0; i < numPoints; i++) {
3089ea844a1aSMatthew Knepley        PetscInt           point = points[2*i], dof, sOffset;
3090ea844a1aSMatthew Knepley        const PetscInt    *perm  = perms ? perms[i] : NULL;
3091ea844a1aSMatthew Knepley        const PetscScalar *rot   = rots  ? rots[i]  : NULL;
3092ea844a1aSMatthew Knepley 
3093ea844a1aSMatthew Knepley        PetscSectionGetDof(section,point,&dof);
3094ea844a1aSMatthew Knepley        PetscSectionGetOffset(section,point,&sOffset);
3095ea844a1aSMatthew Knepley 
3096ea844a1aSMatthew Knepley        if (perm) {for (j = 0; j < dof; j++) {lArray[lOffset + perm[j]]  = sArray[sOffset + j];}}
3097ea844a1aSMatthew Knepley        else      {for (j = 0; j < dof; j++) {lArray[lOffset +      j ]  = sArray[sOffset + j];}}
3098ea844a1aSMatthew Knepley        if (rot)  {for (j = 0; j < dof; j++) {lArray[lOffset +      j ] *= rot[j];             }}
3099ea844a1aSMatthew Knepley        lOffset += dof;
3100ea844a1aSMatthew Knepley      }
3101ea844a1aSMatthew Knepley      PetscSectionRestorePointSyms(section,numPoints,points,&perms,&rots);
3102ea844a1aSMatthew Knepley .ve
3103ea844a1aSMatthew Knepley 
3104ea844a1aSMatthew Knepley   Example of usage, adding dofs into a section array (sArray) from a local array (lArray):
3105ea844a1aSMatthew Knepley .vb
3106ea844a1aSMatthew Knepley      const PetscInt    **perms;
3107ea844a1aSMatthew Knepley      const PetscScalar **rots;
3108ea844a1aSMatthew Knepley      PetscInt            lOffset;
3109ea844a1aSMatthew Knepley 
3110ea844a1aSMatthew Knepley      PetscSectionGetPointSyms(section,numPoints,points,&perms,&rots);
3111ea844a1aSMatthew Knepley      for (i = 0, lOffset = 0; i < numPoints; i++) {
3112ea844a1aSMatthew Knepley        PetscInt           point = points[2*i], dof, sOffset;
3113ea844a1aSMatthew Knepley        const PetscInt    *perm  = perms ? perms[i] : NULL;
3114ea844a1aSMatthew Knepley        const PetscScalar *rot   = rots  ? rots[i]  : NULL;
3115ea844a1aSMatthew Knepley 
3116ea844a1aSMatthew Knepley        PetscSectionGetDof(section,point,&dof);
3117ea844a1aSMatthew Knepley        PetscSectionGetOffset(section,point,&sOff);
3118ea844a1aSMatthew Knepley 
3119ea844a1aSMatthew Knepley        if (perm) {for (j = 0; j < dof; j++) {sArray[sOffset + j] += lArray[lOffset + perm[j]] * (rot ? PetscConj(rot[perm[j]]) : 1.);}}
3120ea844a1aSMatthew Knepley        else      {for (j = 0; j < dof; j++) {sArray[sOffset + j] += lArray[lOffset +      j ] * (rot ? PetscConj(rot[     j ]) : 1.);}}
3121ea844a1aSMatthew Knepley        offset += dof;
3122ea844a1aSMatthew Knepley      }
3123ea844a1aSMatthew Knepley      PetscSectionRestorePointSyms(section,numPoints,points,&perms,&rots);
3124ea844a1aSMatthew Knepley .ve
3125ea844a1aSMatthew Knepley 
3126ea844a1aSMatthew Knepley   Level: developer
3127ea844a1aSMatthew Knepley 
3128db781477SPatrick Sanan .seealso: `PetscSectionRestorePointSyms()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`
3129ea844a1aSMatthew Knepley @*/
3130*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetPointSyms(PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) {
3131ea844a1aSMatthew Knepley   PetscSectionSym sym;
3132ea844a1aSMatthew Knepley 
3133ea844a1aSMatthew Knepley   PetscFunctionBegin;
3134ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
3135ea844a1aSMatthew Knepley   if (numPoints) PetscValidIntPointer(points, 3);
3136ea844a1aSMatthew Knepley   if (perms) *perms = NULL;
3137ea844a1aSMatthew Knepley   if (rots) *rots = NULL;
3138ea844a1aSMatthew Knepley   sym = section->sym;
3139ea844a1aSMatthew Knepley   if (sym && (perms || rots)) {
3140ea844a1aSMatthew Knepley     SymWorkLink link;
3141ea844a1aSMatthew Knepley 
3142ea844a1aSMatthew Knepley     if (sym->workin) {
3143ea844a1aSMatthew Knepley       link        = sym->workin;
3144ea844a1aSMatthew Knepley       sym->workin = sym->workin->next;
3145ea844a1aSMatthew Knepley     } else {
31469566063dSJacob Faibussowitsch       PetscCall(PetscNewLog(sym, &link));
3147ea844a1aSMatthew Knepley     }
3148ea844a1aSMatthew Knepley     if (numPoints > link->numPoints) {
31490c99d500SBarry Smith       PetscInt    **perms = (PetscInt **)link->perms;
31500c99d500SBarry Smith       PetscScalar **rots  = (PetscScalar **)link->rots;
31510c99d500SBarry Smith       PetscCall(PetscFree2(perms, rots));
31520c99d500SBarry Smith       PetscCall(PetscMalloc2(numPoints, (PetscInt ***)&link->perms, numPoints, (PetscScalar ***)&link->rots));
3153ea844a1aSMatthew Knepley       link->numPoints = numPoints;
3154ea844a1aSMatthew Knepley     }
3155ea844a1aSMatthew Knepley     link->next   = sym->workout;
3156ea844a1aSMatthew Knepley     sym->workout = link;
31579566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero((PetscInt **)link->perms, numPoints));
31589566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero((PetscInt **)link->rots, numPoints));
31599566063dSJacob Faibussowitsch     PetscCall((*sym->ops->getpoints)(sym, section, numPoints, points, link->perms, link->rots));
3160ea844a1aSMatthew Knepley     if (perms) *perms = link->perms;
3161ea844a1aSMatthew Knepley     if (rots) *rots = link->rots;
3162ea844a1aSMatthew Knepley   }
3163ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3164ea844a1aSMatthew Knepley }
3165ea844a1aSMatthew Knepley 
3166ea844a1aSMatthew Knepley /*@C
3167ea844a1aSMatthew Knepley   PetscSectionRestorePointSyms - Restore the symmetries returned by PetscSectionGetPointSyms()
3168ea844a1aSMatthew Knepley 
316940750d41SVaclav Hapla   Not Collective
3170ea844a1aSMatthew Knepley 
3171ea844a1aSMatthew Knepley   Input Parameters:
3172ea844a1aSMatthew Knepley + section - the section
3173ea844a1aSMatthew Knepley . numPoints - the number of points
3174ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an
3175ea844a1aSMatthew Knepley     arbitrary integer: its interpretation is up to sym.  Orientations are used by DM: for their interpretation in that
3176ea844a1aSMatthew Knepley     context, see DMPlexGetConeOrientation()).
3177ea844a1aSMatthew Knepley 
3178d8d19677SJose E. Roman   Output Parameters:
3179ea844a1aSMatthew Knepley + perms - The permutations for the given orientations: set to NULL at conclusion
3180ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations: set to NULL at conclusion
3181ea844a1aSMatthew Knepley 
3182ea844a1aSMatthew Knepley   Level: developer
3183ea844a1aSMatthew Knepley 
3184db781477SPatrick Sanan .seealso: `PetscSectionGetPointSyms()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`
3185ea844a1aSMatthew Knepley @*/
3186*9371c9d4SSatish Balay PetscErrorCode PetscSectionRestorePointSyms(PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) {
3187ea844a1aSMatthew Knepley   PetscSectionSym sym;
3188ea844a1aSMatthew Knepley 
3189ea844a1aSMatthew Knepley   PetscFunctionBegin;
3190ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
3191ea844a1aSMatthew Knepley   sym = section->sym;
3192ea844a1aSMatthew Knepley   if (sym && (perms || rots)) {
3193ea844a1aSMatthew Knepley     SymWorkLink *p, link;
3194ea844a1aSMatthew Knepley 
3195ea844a1aSMatthew Knepley     for (p = &sym->workout; (link = *p); p = &link->next) {
3196ea844a1aSMatthew Knepley       if ((perms && link->perms == *perms) || (rots && link->rots == *rots)) {
3197ea844a1aSMatthew Knepley         *p          = link->next;
3198ea844a1aSMatthew Knepley         link->next  = sym->workin;
3199ea844a1aSMatthew Knepley         sym->workin = link;
3200ea844a1aSMatthew Knepley         if (perms) *perms = NULL;
3201ea844a1aSMatthew Knepley         if (rots) *rots = NULL;
3202ea844a1aSMatthew Knepley         PetscFunctionReturn(0);
3203ea844a1aSMatthew Knepley       }
3204ea844a1aSMatthew Knepley     }
3205ea844a1aSMatthew Knepley     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out");
3206ea844a1aSMatthew Knepley   }
3207ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3208ea844a1aSMatthew Knepley }
3209ea844a1aSMatthew Knepley 
3210ea844a1aSMatthew Knepley /*@C
3211ea844a1aSMatthew Knepley   PetscSectionGetFieldPointSyms - Get the symmetries for a set of points in a field of a PetscSection under specific orientations.
3212ea844a1aSMatthew Knepley 
321340750d41SVaclav Hapla   Not Collective
3214ea844a1aSMatthew Knepley 
3215ea844a1aSMatthew Knepley   Input Parameters:
3216ea844a1aSMatthew Knepley + section - the section
3217ea844a1aSMatthew Knepley . field - the field of the section
3218ea844a1aSMatthew Knepley . numPoints - the number of points
3219ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an
3220ea844a1aSMatthew Knepley     arbitrary integer: its interpretation is up to sym.  Orientations are used by DM: for their interpretation in that
3221ea844a1aSMatthew Knepley     context, see DMPlexGetConeOrientation()).
3222ea844a1aSMatthew Knepley 
3223d8d19677SJose E. Roman   Output Parameters:
3224ea844a1aSMatthew Knepley + perms - The permutations for the given orientations (or NULL if there is no symmetry or the permutation is the identity).
3225ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations (or NULL if there is no symmetry or the rotations are all
3226ea844a1aSMatthew Knepley     identity).
3227ea844a1aSMatthew Knepley 
3228ea844a1aSMatthew Knepley   Level: developer
3229ea844a1aSMatthew Knepley 
3230db781477SPatrick Sanan .seealso: `PetscSectionGetPointSyms()`, `PetscSectionRestoreFieldPointSyms()`
3231ea844a1aSMatthew Knepley @*/
3232*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetFieldPointSyms(PetscSection section, PetscInt field, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) {
3233ea844a1aSMatthew Knepley   PetscFunctionBegin;
3234ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
323508401ef6SPierre Jolivet   PetscCheck(field <= section->numFields, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "field %" PetscInt_FMT " greater than number of fields (%" PetscInt_FMT ") in section", field, section->numFields);
32369566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetPointSyms(section->field[field], numPoints, points, perms, rots));
3237ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3238ea844a1aSMatthew Knepley }
3239ea844a1aSMatthew Knepley 
3240ea844a1aSMatthew Knepley /*@C
3241ea844a1aSMatthew Knepley   PetscSectionRestoreFieldPointSyms - Restore the symmetries returned by PetscSectionGetFieldPointSyms()
3242ea844a1aSMatthew Knepley 
324340750d41SVaclav Hapla   Not Collective
3244ea844a1aSMatthew Knepley 
3245ea844a1aSMatthew Knepley   Input Parameters:
3246ea844a1aSMatthew Knepley + section - the section
3247ea844a1aSMatthew Knepley . field - the field number
3248ea844a1aSMatthew Knepley . numPoints - the number of points
3249ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an
3250ea844a1aSMatthew Knepley     arbitrary integer: its interpretation is up to sym.  Orientations are used by DM: for their interpretation in that
3251ea844a1aSMatthew Knepley     context, see DMPlexGetConeOrientation()).
3252ea844a1aSMatthew Knepley 
3253d8d19677SJose E. Roman   Output Parameters:
3254ea844a1aSMatthew Knepley + perms - The permutations for the given orientations: set to NULL at conclusion
3255ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations: set to NULL at conclusion
3256ea844a1aSMatthew Knepley 
3257ea844a1aSMatthew Knepley   Level: developer
3258ea844a1aSMatthew Knepley 
3259db781477SPatrick Sanan .seealso: `PetscSectionRestorePointSyms()`, `petscSectionGetFieldPointSyms()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`
3260ea844a1aSMatthew Knepley @*/
3261*9371c9d4SSatish Balay PetscErrorCode PetscSectionRestoreFieldPointSyms(PetscSection section, PetscInt field, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) {
3262ea844a1aSMatthew Knepley   PetscFunctionBegin;
3263ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1);
326408401ef6SPierre Jolivet   PetscCheck(field <= section->numFields, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "field %" PetscInt_FMT " greater than number of fields (%" PetscInt_FMT ") in section", field, section->numFields);
32659566063dSJacob Faibussowitsch   PetscCall(PetscSectionRestorePointSyms(section->field[field], numPoints, points, perms, rots));
3266ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3267ea844a1aSMatthew Knepley }
3268ea844a1aSMatthew Knepley 
3269ea844a1aSMatthew Knepley /*@
3270b004864fSMatthew G. Knepley   PetscSectionSymCopy - Copy the symmetries, assuming that the point structure is compatible
3271b004864fSMatthew G. Knepley 
327240750d41SVaclav Hapla   Not Collective
3273b004864fSMatthew G. Knepley 
3274b004864fSMatthew G. Knepley   Input Parameter:
3275b004864fSMatthew G. Knepley . sym - the PetscSectionSym
3276b004864fSMatthew G. Knepley 
3277b004864fSMatthew G. Knepley   Output Parameter:
3278b004864fSMatthew G. Knepley . nsym - the equivalent symmetries
3279b004864fSMatthew G. Knepley 
3280b004864fSMatthew G. Knepley   Level: developer
3281b004864fSMatthew G. Knepley 
3282db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()`
3283b004864fSMatthew G. Knepley @*/
3284*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymCopy(PetscSectionSym sym, PetscSectionSym nsym) {
3285b004864fSMatthew G. Knepley   PetscFunctionBegin;
3286b004864fSMatthew G. Knepley   PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
3287b004864fSMatthew G. Knepley   PetscValidHeaderSpecific(nsym, PETSC_SECTION_SYM_CLASSID, 2);
3288dbbe0bcdSBarry Smith   PetscTryTypeMethod(sym, copy, nsym);
3289b004864fSMatthew G. Knepley   PetscFunctionReturn(0);
3290b004864fSMatthew G. Knepley }
3291b004864fSMatthew G. Knepley 
3292b004864fSMatthew G. Knepley /*@
3293b004864fSMatthew G. Knepley   PetscSectionSymDistribute - Distribute the symmetries in accordance with the input SF
3294b004864fSMatthew G. Knepley 
3295b004864fSMatthew G. Knepley   Collective
3296b004864fSMatthew G. Knepley 
3297b004864fSMatthew G. Knepley   Input Parameters:
3298b004864fSMatthew G. Knepley + sym - the PetscSectionSym
3299b004864fSMatthew G. Knepley - migrationSF - the distribution map from roots to leaves
3300b004864fSMatthew G. Knepley 
3301b004864fSMatthew G. Knepley   Output Parameters:
3302b004864fSMatthew G. Knepley . dsym - the redistributed symmetries
3303b004864fSMatthew G. Knepley 
3304b004864fSMatthew G. Knepley   Level: developer
3305b004864fSMatthew G. Knepley 
3306db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()`
3307b004864fSMatthew G. Knepley @*/
3308*9371c9d4SSatish Balay PetscErrorCode PetscSectionSymDistribute(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) {
3309b004864fSMatthew G. Knepley   PetscFunctionBegin;
3310b004864fSMatthew G. Knepley   PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
3311b004864fSMatthew G. Knepley   PetscValidHeaderSpecific(migrationSF, PETSCSF_CLASSID, 2);
3312b004864fSMatthew G. Knepley   PetscValidPointer(dsym, 3);
3313dbbe0bcdSBarry Smith   PetscTryTypeMethod(sym, distribute, migrationSF, dsym);
3314b004864fSMatthew G. Knepley   PetscFunctionReturn(0);
3315b004864fSMatthew G. Knepley }
3316b004864fSMatthew G. Knepley 
3317b004864fSMatthew G. Knepley /*@
3318ea844a1aSMatthew Knepley   PetscSectionGetUseFieldOffsets - Get the flag to use field offsets directly in a global section, rather than just the point offset
3319ea844a1aSMatthew Knepley 
332040750d41SVaclav Hapla   Not Collective
3321ea844a1aSMatthew Knepley 
3322ea844a1aSMatthew Knepley   Input Parameter:
3323ea844a1aSMatthew Knepley . s - the global PetscSection
3324ea844a1aSMatthew Knepley 
3325ea844a1aSMatthew Knepley   Output Parameters:
3326ea844a1aSMatthew Knepley . flg - the flag
3327ea844a1aSMatthew Knepley 
3328ea844a1aSMatthew Knepley   Level: developer
3329ea844a1aSMatthew Knepley 
3330db781477SPatrick Sanan .seealso: `PetscSectionSetChart()`, `PetscSectionCreate()`
3331ea844a1aSMatthew Knepley @*/
3332*9371c9d4SSatish Balay PetscErrorCode PetscSectionGetUseFieldOffsets(PetscSection s, PetscBool *flg) {
3333ea844a1aSMatthew Knepley   PetscFunctionBegin;
3334ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
3335ea844a1aSMatthew Knepley   *flg = s->useFieldOff;
3336ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3337ea844a1aSMatthew Knepley }
3338ea844a1aSMatthew Knepley 
3339ea844a1aSMatthew Knepley /*@
3340ea844a1aSMatthew Knepley   PetscSectionSetUseFieldOffsets - Set the flag to use field offsets directly in a global section, rather than just the point offset
3341ea844a1aSMatthew Knepley 
334240750d41SVaclav Hapla   Not Collective
3343ea844a1aSMatthew Knepley 
3344ea844a1aSMatthew Knepley   Input Parameters:
3345ea844a1aSMatthew Knepley + s   - the global PetscSection
3346ea844a1aSMatthew Knepley - flg - the flag
3347ea844a1aSMatthew Knepley 
3348ea844a1aSMatthew Knepley   Level: developer
3349ea844a1aSMatthew Knepley 
3350db781477SPatrick Sanan .seealso: `PetscSectionGetUseFieldOffsets()`, `PetscSectionSetChart()`, `PetscSectionCreate()`
3351ea844a1aSMatthew Knepley @*/
3352*9371c9d4SSatish Balay PetscErrorCode PetscSectionSetUseFieldOffsets(PetscSection s, PetscBool flg) {
3353ea844a1aSMatthew Knepley   PetscFunctionBegin;
3354ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
3355ea844a1aSMatthew Knepley   s->useFieldOff = flg;
3356ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3357ea844a1aSMatthew Knepley }
3358ea844a1aSMatthew Knepley 
3359ea844a1aSMatthew Knepley #define PetscSectionExpandPoints_Loop(TYPE) \
3360ea844a1aSMatthew Knepley   { \
3361ea844a1aSMatthew Knepley     PetscInt i, n, o0, o1, size; \
3362ea844a1aSMatthew Knepley     TYPE    *a0 = (TYPE *)origArray, *a1; \
33639566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetStorageSize(s, &size)); \
33649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(size, &a1)); \
3365ea844a1aSMatthew Knepley     for (i = 0; i < npoints; i++) { \
33669566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(origSection, points_[i], &o0)); \
33679566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(s, i, &o1)); \
33689566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetDof(s, i, &n)); \
33699566063dSJacob Faibussowitsch       PetscCall(PetscMemcpy(&a1[o1], &a0[o0], n *unitsize)); \
3370ea844a1aSMatthew Knepley     } \
3371ea844a1aSMatthew Knepley     *newArray = (void *)a1; \
3372ea844a1aSMatthew Knepley   }
3373ea844a1aSMatthew Knepley 
3374ea844a1aSMatthew Knepley /*@
3375ea844a1aSMatthew Knepley   PetscSectionExtractDofsFromArray - Extracts elements of an array corresponding to DOFs of specified points.
3376ea844a1aSMatthew Knepley 
337740750d41SVaclav Hapla   Not Collective
3378ea844a1aSMatthew Knepley 
3379ea844a1aSMatthew Knepley   Input Parameters:
3380ea844a1aSMatthew Knepley + origSection - the PetscSection describing the layout of the array
3381ea844a1aSMatthew Knepley . dataType - MPI_Datatype describing the data type of the array (currently only MPIU_INT, MPIU_SCALAR, MPIU_REAL)
3382ea844a1aSMatthew Knepley . origArray - the array; its size must be equal to the storage size of origSection
3383ea844a1aSMatthew Knepley - points - IS with points to extract; its indices must lie in the chart of origSection
3384ea844a1aSMatthew Knepley 
3385ea844a1aSMatthew Knepley   Output Parameters:
3386ea844a1aSMatthew Knepley + newSection - the new PetscSection desribing the layout of the new array (with points renumbered 0,1,... but preserving numbers of DOFs)
3387ea844a1aSMatthew Knepley - newArray - the array of the extracted DOFs; its size is the storage size of newSection
3388ea844a1aSMatthew Knepley 
3389ea844a1aSMatthew Knepley   Level: developer
3390ea844a1aSMatthew Knepley 
3391db781477SPatrick Sanan .seealso: `PetscSectionGetChart()`, `PetscSectionGetDof()`, `PetscSectionGetStorageSize()`, `PetscSectionCreate()`
3392ea844a1aSMatthew Knepley @*/
3393*9371c9d4SSatish Balay PetscErrorCode PetscSectionExtractDofsFromArray(PetscSection origSection, MPI_Datatype dataType, const void *origArray, IS points, PetscSection *newSection, void *newArray[]) {
3394ea844a1aSMatthew Knepley   PetscSection    s;
3395ea844a1aSMatthew Knepley   const PetscInt *points_;
3396ea844a1aSMatthew Knepley   PetscInt        i, n, npoints, pStart, pEnd;
3397ea844a1aSMatthew Knepley   PetscMPIInt     unitsize;
3398ea844a1aSMatthew Knepley 
3399ea844a1aSMatthew Knepley   PetscFunctionBegin;
3400ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(origSection, PETSC_SECTION_CLASSID, 1);
3401ea844a1aSMatthew Knepley   PetscValidPointer(origArray, 3);
3402ea844a1aSMatthew Knepley   PetscValidHeaderSpecific(points, IS_CLASSID, 4);
3403ea844a1aSMatthew Knepley   if (newSection) PetscValidPointer(newSection, 5);
3404ea844a1aSMatthew Knepley   if (newArray) PetscValidPointer(newArray, 6);
34059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Type_size(dataType, &unitsize));
34069566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(points, &npoints));
34079566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(points, &points_));
34089566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(origSection, &pStart, &pEnd));
34099566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PETSC_COMM_SELF, &s));
34109566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(s, 0, npoints));
3411ea844a1aSMatthew Knepley   for (i = 0; i < npoints; i++) {
3412c9cc58a2SBarry Smith     PetscCheck(points_[i] >= pStart && points_[i] < pEnd, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "point %" PetscInt_FMT " (index %" PetscInt_FMT ") in input IS out of input section's chart", points_[i], i);
34139566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(origSection, points_[i], &n));
34149566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(s, i, n));
3415ea844a1aSMatthew Knepley   }
34169566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(s));
3417ea844a1aSMatthew Knepley   if (newArray) {
3418*9371c9d4SSatish Balay     if (dataType == MPIU_INT) {
3419*9371c9d4SSatish Balay       PetscSectionExpandPoints_Loop(PetscInt);
3420*9371c9d4SSatish Balay     } else if (dataType == MPIU_SCALAR) {
3421*9371c9d4SSatish Balay       PetscSectionExpandPoints_Loop(PetscScalar);
3422*9371c9d4SSatish Balay     } else if (dataType == MPIU_REAL) {
3423*9371c9d4SSatish Balay       PetscSectionExpandPoints_Loop(PetscReal);
3424*9371c9d4SSatish Balay     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "not implemented for this MPI_Datatype");
3425ea844a1aSMatthew Knepley   }
3426ea844a1aSMatthew Knepley   if (newSection) {
3427ea844a1aSMatthew Knepley     *newSection = s;
3428ea844a1aSMatthew Knepley   } else {
34299566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&s));
3430ea844a1aSMatthew Knepley   }
34319566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(points, &points_));
3432ea844a1aSMatthew Knepley   PetscFunctionReturn(0);
3433ea844a1aSMatthew Knepley }
3434