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 @*/ 369371c9d4SSatish 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 @*/ 819371c9d4SSatish 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 @*/ 1689371c9d4SSatish 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 @*/ 1929371c9d4SSatish 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 @*/ 2239371c9d4SSatish 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 @*/ 3229371c9d4SSatish 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 @*/ 3439371c9d4SSatish 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 @*/ 3879371c9d4SSatish 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 @*/ 4109371c9d4SSatish 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 @*/ 4359371c9d4SSatish 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 @*/ 4609371c9d4SSatish 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 @*/ 4879371c9d4SSatish 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 @*/ 5109371c9d4SSatish 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) { 51748a46eb9SPierre Jolivet 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 @*/ 5509371c9d4SSatish 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 @*/ 5729371c9d4SSatish 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)); 58848a46eb9SPierre Jolivet 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 @*/ 6079371c9d4SSatish Balay PetscErrorCode PetscSectionGetPermutation(PetscSection s, IS *perm) { 608ea844a1aSMatthew Knepley PetscFunctionBegin; 609ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 6109371c9d4SSatish Balay if (perm) { 6119371c9d4SSatish Balay PetscValidPointer(perm, 2); 6129371c9d4SSatish Balay *perm = s->perm; 6139371c9d4SSatish 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 @*/ 6309371c9d4SSatish 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 @*/ 6609371c9d4SSatish 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 @*/ 6819371c9d4SSatish 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 @*/ 7049371c9d4SSatish 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 @*/ 7259371c9d4SSatish 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 @*/ 7499371c9d4SSatish 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 @*/ 7729371c9d4SSatish 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 @*/ 7959371c9d4SSatish 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 @*/ 8219371c9d4SSatish 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 @*/ 8459371c9d4SSatish 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 @*/ 8689371c9d4SSatish 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 @*/ 8929371c9d4SSatish 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 @*/ 9169371c9d4SSatish 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 @*/ 9409371c9d4SSatish 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 @*/ 9679371c9d4SSatish 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 @*/ 9919371c9d4SSatish 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 @*/ 10149371c9d4SSatish 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 @*/ 10349371c9d4SSatish 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 @*/ 10589371c9d4SSatish 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*ad540459SPierre Jolivet 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 @*/ 11319371c9d4SSatish 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*ad540459SPierre Jolivet 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 @*/ 11609371c9d4SSatish 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 @*/ 11869371c9d4SSatish 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 @*/ 12199371c9d4SSatish 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 @*/ 13499371c9d4SSatish 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) { 13919371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 13929371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 13939371c9d4SSatish 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) { 14189371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 14199371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 14209371c9d4SSatish 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 @*/ 14469371c9d4SSatish 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 @*/ 14829371c9d4SSatish 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 @*/ 15199371c9d4SSatish 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*ad540459SPierre Jolivet 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 @*/ 15449371c9d4SSatish 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 @*/ 15699371c9d4SSatish 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 @*/ 15959371c9d4SSatish 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 @*/ 16239371c9d4SSatish 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 @*/ 16529371c9d4SSatish 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); 16579371c9d4SSatish Balay if (s->atlasOff) { 16589371c9d4SSatish Balay os = s->atlasOff[0]; 16599371c9d4SSatish Balay oe = s->atlasOff[0]; 16609371c9d4SSatish 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 @*/ 16949371c9d4SSatish 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 @*/ 17849371c9d4SSatish 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 18819371c9d4SSatish 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 @*/ 19889371c9d4SSatish 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 @*/ 20139371c9d4SSatish 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 20199371c9d4SSatish 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) { 203348a46eb9SPierre Jolivet 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 @*/ 20639371c9d4SSatish 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 @*/ 20919371c9d4SSatish 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 @*/ 21439371c9d4SSatish 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 21609371c9d4SSatish 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 @*/ 21869371c9d4SSatish 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])); 219448a46eb9SPierre Jolivet 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 @*/ 22339371c9d4SSatish 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 22469371c9d4SSatish 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 22559371c9d4SSatish 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) { 22959371c9d4SSatish Balay if ((cInd < cDim) && (i == cDof[cInd])) { 22969371c9d4SSatish Balay ++cInd; 22979371c9d4SSatish Balay continue; 22989371c9d4SSatish Balay } 2299ea844a1aSMatthew Knepley array[i] = values[i]; 2300ea844a1aSMatthew Knepley } 2301ea844a1aSMatthew Knepley } else { 2302ea844a1aSMatthew Knepley for (i = 0; i < dim; ++i) { 23039371c9d4SSatish Balay if ((cInd < cDim) && (i == cDof[cInd])) { 23049371c9d4SSatish Balay ++cInd; 23059371c9d4SSatish Balay continue; 23069371c9d4SSatish 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) { 23249371c9d4SSatish Balay if ((cInd < sDim) && (j == cDof[cInd + cOffset])) { 23259371c9d4SSatish Balay ++cInd; 23269371c9d4SSatish Balay continue; 23279371c9d4SSatish 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 @*/ 23539371c9d4SSatish 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 @*/ 23799371c9d4SSatish 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 @*/ 24049371c9d4SSatish 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*ad540459SPierre Jolivet 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 @*/ 24419371c9d4SSatish 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 @*/ 24679371c9d4SSatish 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 @*/ 24979371c9d4SSatish 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 @*/ 25819371c9d4SSatish 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(§ion->clSection)); 25919566063dSJacob Faibussowitsch PetscCall(ISDestroy(§ion->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 @*/ 26169371c9d4SSatish 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 26289371c9d4SSatish 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(§ion->clSection)); 26389566063dSJacob Faibussowitsch PetscCall(ISDestroy(§ion->clPoints)); 2639ea844a1aSMatthew Knepley } 2640ea844a1aSMatthew Knepley section->clObj = obj; 26419566063dSJacob Faibussowitsch if (!section->clHash) PetscCall(PetscClPermCreate(§ion->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 @*/ 26839371c9d4SSatish 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 26979371c9d4SSatish 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 @*/ 27319371c9d4SSatish 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 27409371c9d4SSatish 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 @*/ 27749371c9d4SSatish 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 @*/ 27979371c9d4SSatish 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 @*/ 28249371c9d4SSatish 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 @*/ 28459371c9d4SSatish 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 @*/ 28799371c9d4SSatish 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 @*/ 29039371c9d4SSatish 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 @*/ 29229371c9d4SSatish 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); 29289371c9d4SSatish Balay if (--((PetscObject)(*sym))->refct > 0) { 29299371c9d4SSatish Balay *sym = NULL; 29309371c9d4SSatish Balay PetscFunctionReturn(0); 2931ea844a1aSMatthew Knepley } 293248a46eb9SPierre Jolivet 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 @*/ 29599371c9d4SSatish Balay PetscErrorCode PetscSectionSymView(PetscSectionSym sym, PetscViewer viewer) { 2960ea844a1aSMatthew Knepley PetscFunctionBegin; 2961ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 296248a46eb9SPierre Jolivet 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 @*/ 29839371c9d4SSatish 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 @*/ 30119371c9d4SSatish 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 @*/ 30329371c9d4SSatish 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 @*/ 30569371c9d4SSatish 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 @*/ 31309371c9d4SSatish 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 @*/ 31869371c9d4SSatish 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 @*/ 32329371c9d4SSatish 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 @*/ 32619371c9d4SSatish 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 @*/ 32849371c9d4SSatish 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 @*/ 33089371c9d4SSatish 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 @*/ 33329371c9d4SSatish 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 @*/ 33529371c9d4SSatish 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 @*/ 33939371c9d4SSatish 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) { 34189371c9d4SSatish Balay if (dataType == MPIU_INT) { 34199371c9d4SSatish Balay PetscSectionExpandPoints_Loop(PetscInt); 34209371c9d4SSatish Balay } else if (dataType == MPIU_SCALAR) { 34219371c9d4SSatish Balay PetscSectionExpandPoints_Loop(PetscScalar); 34229371c9d4SSatish Balay } else if (dataType == MPIU_REAL) { 34239371c9d4SSatish Balay PetscSectionExpandPoints_Loop(PetscReal); 34249371c9d4SSatish 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