1*ea844a1aSMatthew Knepley /* 2*ea844a1aSMatthew Knepley This file contains routines for basic section object implementation. 3*ea844a1aSMatthew Knepley */ 4*ea844a1aSMatthew Knepley 5*ea844a1aSMatthew Knepley #include <petsc/private/sectionimpl.h> /*I "petscsection.h" I*/ 6*ea844a1aSMatthew Knepley #include <petscsection.h> 7*ea844a1aSMatthew Knepley #include <petscsf.h> 8*ea844a1aSMatthew Knepley #include <petscviewer.h> 9*ea844a1aSMatthew Knepley 10*ea844a1aSMatthew Knepley PetscClassId PETSC_SECTION_CLASSID; 11*ea844a1aSMatthew Knepley 12*ea844a1aSMatthew Knepley /*@ 13*ea844a1aSMatthew Knepley PetscSectionCreate - Allocates PetscSection space and sets the map contents to the default. 14*ea844a1aSMatthew Knepley 15*ea844a1aSMatthew Knepley Collective 16*ea844a1aSMatthew Knepley 17*ea844a1aSMatthew Knepley Input Parameters: 18*ea844a1aSMatthew Knepley + comm - the MPI communicator 19*ea844a1aSMatthew Knepley - s - pointer to the section 20*ea844a1aSMatthew Knepley 21*ea844a1aSMatthew Knepley Level: beginner 22*ea844a1aSMatthew Knepley 23*ea844a1aSMatthew Knepley Notes: 24*ea844a1aSMatthew Knepley Typical calling sequence 25*ea844a1aSMatthew Knepley $ PetscSectionCreate(MPI_Comm,PetscSection *); 26*ea844a1aSMatthew Knepley $ PetscSectionSetNumFields(PetscSection, numFields); 27*ea844a1aSMatthew Knepley $ PetscSectionSetChart(PetscSection,low,high); 28*ea844a1aSMatthew Knepley $ PetscSectionSetDof(PetscSection,point,numdof); 29*ea844a1aSMatthew Knepley $ PetscSectionSetUp(PetscSection); 30*ea844a1aSMatthew Knepley $ PetscSectionGetOffset(PetscSection,point,PetscInt *); 31*ea844a1aSMatthew Knepley $ PetscSectionDestroy(PetscSection); 32*ea844a1aSMatthew Knepley 33*ea844a1aSMatthew Knepley The PetscSection object and methods are intended to be used in the PETSc Vec and Mat implementions; it is 34*ea844a1aSMatthew Knepley recommended they not be used in user codes unless you really gain something in their use. 35*ea844a1aSMatthew Knepley 36*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionDestroy() 37*ea844a1aSMatthew Knepley @*/ 38*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreate(MPI_Comm comm, PetscSection *s) 39*ea844a1aSMatthew Knepley { 40*ea844a1aSMatthew Knepley PetscErrorCode ierr; 41*ea844a1aSMatthew Knepley 42*ea844a1aSMatthew Knepley PetscFunctionBegin; 43*ea844a1aSMatthew Knepley PetscValidPointer(s,2); 44*ea844a1aSMatthew Knepley ierr = ISInitializePackage();CHKERRQ(ierr); 45*ea844a1aSMatthew Knepley 46*ea844a1aSMatthew Knepley ierr = PetscHeaderCreate(*s,PETSC_SECTION_CLASSID,"PetscSection","Section","IS",comm,PetscSectionDestroy,PetscSectionView);CHKERRQ(ierr); 47*ea844a1aSMatthew Knepley 48*ea844a1aSMatthew Knepley (*s)->pStart = -1; 49*ea844a1aSMatthew Knepley (*s)->pEnd = -1; 50*ea844a1aSMatthew Knepley (*s)->perm = NULL; 51*ea844a1aSMatthew Knepley (*s)->pointMajor = PETSC_TRUE; 52*ea844a1aSMatthew Knepley (*s)->maxDof = 0; 53*ea844a1aSMatthew Knepley (*s)->atlasDof = NULL; 54*ea844a1aSMatthew Knepley (*s)->atlasOff = NULL; 55*ea844a1aSMatthew Knepley (*s)->bc = NULL; 56*ea844a1aSMatthew Knepley (*s)->bcIndices = NULL; 57*ea844a1aSMatthew Knepley (*s)->setup = PETSC_FALSE; 58*ea844a1aSMatthew Knepley (*s)->numFields = 0; 59*ea844a1aSMatthew Knepley (*s)->fieldNames = NULL; 60*ea844a1aSMatthew Knepley (*s)->field = NULL; 61*ea844a1aSMatthew Knepley (*s)->useFieldOff = PETSC_FALSE; 62*ea844a1aSMatthew Knepley (*s)->clObj = NULL; 63*ea844a1aSMatthew Knepley (*s)->clSection = NULL; 64*ea844a1aSMatthew Knepley (*s)->clPoints = NULL; 65*ea844a1aSMatthew Knepley (*s)->clSize = 0; 66*ea844a1aSMatthew Knepley (*s)->clPerm = NULL; 67*ea844a1aSMatthew Knepley (*s)->clInvPerm = NULL; 68*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 69*ea844a1aSMatthew Knepley } 70*ea844a1aSMatthew Knepley 71*ea844a1aSMatthew Knepley /*@ 72*ea844a1aSMatthew Knepley PetscSectionCopy - Creates a shallow (if possible) copy of the PetscSection 73*ea844a1aSMatthew Knepley 74*ea844a1aSMatthew Knepley Collective 75*ea844a1aSMatthew Knepley 76*ea844a1aSMatthew Knepley Input Parameter: 77*ea844a1aSMatthew Knepley . section - the PetscSection 78*ea844a1aSMatthew Knepley 79*ea844a1aSMatthew Knepley Output Parameter: 80*ea844a1aSMatthew Knepley . newSection - the copy 81*ea844a1aSMatthew Knepley 82*ea844a1aSMatthew Knepley Level: intermediate 83*ea844a1aSMatthew Knepley 84*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate(), PetscSectionDestroy() 85*ea844a1aSMatthew Knepley @*/ 86*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCopy(PetscSection section, PetscSection newSection) 87*ea844a1aSMatthew Knepley { 88*ea844a1aSMatthew Knepley PetscSectionSym sym; 89*ea844a1aSMatthew Knepley IS perm; 90*ea844a1aSMatthew Knepley PetscInt numFields, f, pStart, pEnd, p; 91*ea844a1aSMatthew Knepley PetscErrorCode ierr; 92*ea844a1aSMatthew Knepley 93*ea844a1aSMatthew Knepley PetscFunctionBegin; 94*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1); 95*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(newSection, PETSC_SECTION_CLASSID, 2); 96*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 97*ea844a1aSMatthew Knepley if (numFields) {ierr = PetscSectionSetNumFields(newSection, numFields);CHKERRQ(ierr);} 98*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 99*ea844a1aSMatthew Knepley const char *name = NULL; 100*ea844a1aSMatthew Knepley PetscInt numComp = 0; 101*ea844a1aSMatthew Knepley 102*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldName(section, f, &name);CHKERRQ(ierr); 103*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldName(newSection, f, name);CHKERRQ(ierr); 104*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(section, f, &numComp);CHKERRQ(ierr); 105*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(newSection, f, numComp);CHKERRQ(ierr); 106*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldSym(section, f, &sym);CHKERRQ(ierr); 107*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldSym(newSection, f, sym);CHKERRQ(ierr); 108*ea844a1aSMatthew Knepley } 109*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 110*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(newSection, pStart, pEnd);CHKERRQ(ierr); 111*ea844a1aSMatthew Knepley ierr = PetscSectionGetPermutation(section, &perm);CHKERRQ(ierr); 112*ea844a1aSMatthew Knepley ierr = PetscSectionSetPermutation(newSection, perm);CHKERRQ(ierr); 113*ea844a1aSMatthew Knepley ierr = PetscSectionGetSym(section, &sym);CHKERRQ(ierr); 114*ea844a1aSMatthew Knepley ierr = PetscSectionSetSym(newSection, sym);CHKERRQ(ierr); 115*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 116*ea844a1aSMatthew Knepley PetscInt dof, cdof, fcdof = 0; 117*ea844a1aSMatthew Knepley 118*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 119*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(newSection, p, dof);CHKERRQ(ierr); 120*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 121*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetConstraintDof(newSection, p, cdof);CHKERRQ(ierr);} 122*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 123*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(section, p, f, &dof);CHKERRQ(ierr); 124*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldDof(newSection, p, f, dof);CHKERRQ(ierr); 125*ea844a1aSMatthew Knepley if (cdof) { 126*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 127*ea844a1aSMatthew Knepley if (fcdof) {ierr = PetscSectionSetFieldConstraintDof(newSection, p, f, fcdof);CHKERRQ(ierr);} 128*ea844a1aSMatthew Knepley } 129*ea844a1aSMatthew Knepley } 130*ea844a1aSMatthew Knepley } 131*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(newSection);CHKERRQ(ierr); 132*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 133*ea844a1aSMatthew Knepley PetscInt off, cdof, fcdof = 0; 134*ea844a1aSMatthew Knepley const PetscInt *cInd; 135*ea844a1aSMatthew Knepley 136*ea844a1aSMatthew Knepley /* Must set offsets in case they do not agree with the prefix sums */ 137*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 138*ea844a1aSMatthew Knepley ierr = PetscSectionSetOffset(newSection, p, off);CHKERRQ(ierr); 139*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 140*ea844a1aSMatthew Knepley if (cdof) { 141*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cInd);CHKERRQ(ierr); 142*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(newSection, p, cInd);CHKERRQ(ierr); 143*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 144*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 145*ea844a1aSMatthew Knepley if (fcdof) { 146*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(section, p, f, &cInd);CHKERRQ(ierr); 147*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldConstraintIndices(newSection, p, f, cInd);CHKERRQ(ierr); 148*ea844a1aSMatthew Knepley } 149*ea844a1aSMatthew Knepley } 150*ea844a1aSMatthew Knepley } 151*ea844a1aSMatthew Knepley } 152*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 153*ea844a1aSMatthew Knepley } 154*ea844a1aSMatthew Knepley 155*ea844a1aSMatthew Knepley /*@ 156*ea844a1aSMatthew Knepley PetscSectionClone - Creates a shallow (if possible) copy of the PetscSection 157*ea844a1aSMatthew Knepley 158*ea844a1aSMatthew Knepley Collective 159*ea844a1aSMatthew Knepley 160*ea844a1aSMatthew Knepley Input Parameter: 161*ea844a1aSMatthew Knepley . section - the PetscSection 162*ea844a1aSMatthew Knepley 163*ea844a1aSMatthew Knepley Output Parameter: 164*ea844a1aSMatthew Knepley . newSection - the copy 165*ea844a1aSMatthew Knepley 166*ea844a1aSMatthew Knepley Level: beginner 167*ea844a1aSMatthew Knepley 168*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate(), PetscSectionDestroy() 169*ea844a1aSMatthew Knepley @*/ 170*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionClone(PetscSection section, PetscSection *newSection) 171*ea844a1aSMatthew Knepley { 172*ea844a1aSMatthew Knepley PetscErrorCode ierr; 173*ea844a1aSMatthew Knepley 174*ea844a1aSMatthew Knepley PetscFunctionBegin; 175*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1); 176*ea844a1aSMatthew Knepley PetscValidPointer(newSection, 2); 177*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) section), newSection);CHKERRQ(ierr); 178*ea844a1aSMatthew Knepley ierr = PetscSectionCopy(section, *newSection);CHKERRQ(ierr); 179*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 180*ea844a1aSMatthew Knepley } 181*ea844a1aSMatthew Knepley 182*ea844a1aSMatthew Knepley /*@ 183*ea844a1aSMatthew Knepley PetscSectionSetFromOptions - sets parameters in a PetscSection from the options database 184*ea844a1aSMatthew Knepley 185*ea844a1aSMatthew Knepley Collective on PetscSection 186*ea844a1aSMatthew Knepley 187*ea844a1aSMatthew Knepley Input Parameter: 188*ea844a1aSMatthew Knepley . section - the PetscSection 189*ea844a1aSMatthew Knepley 190*ea844a1aSMatthew Knepley Options Database: 191*ea844a1aSMatthew Knepley . -petscsection_point_major the dof order 192*ea844a1aSMatthew Knepley 193*ea844a1aSMatthew Knepley Level: intermediate 194*ea844a1aSMatthew Knepley 195*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate(), PetscSectionDestroy() 196*ea844a1aSMatthew Knepley @*/ 197*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFromOptions(PetscSection s) 198*ea844a1aSMatthew Knepley { 199*ea844a1aSMatthew Knepley PetscErrorCode ierr; 200*ea844a1aSMatthew Knepley 201*ea844a1aSMatthew Knepley PetscFunctionBegin; 202*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 203*ea844a1aSMatthew Knepley ierr = PetscObjectOptionsBegin((PetscObject) s);CHKERRQ(ierr); 204*ea844a1aSMatthew Knepley ierr = PetscOptionsBool("-petscsection_point_major", "The for ordering, either point major or field major", "PetscSectionSetPointMajor", s->pointMajor, &s->pointMajor, NULL);CHKERRQ(ierr); 205*ea844a1aSMatthew Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 206*ea844a1aSMatthew Knepley ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) s);CHKERRQ(ierr); 207*ea844a1aSMatthew Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 208*ea844a1aSMatthew Knepley ierr = PetscObjectViewFromOptions((PetscObject) s, NULL, "-petscsection_view");CHKERRQ(ierr); 209*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 210*ea844a1aSMatthew Knepley } 211*ea844a1aSMatthew Knepley 212*ea844a1aSMatthew Knepley /*@ 213*ea844a1aSMatthew Knepley PetscSectionCompare - Compares two sections 214*ea844a1aSMatthew Knepley 215*ea844a1aSMatthew Knepley Collective on PetscSection 216*ea844a1aSMatthew Knepley 217*ea844a1aSMatthew Knepley Input Parameterss: 218*ea844a1aSMatthew Knepley + s1 - the first PetscSection 219*ea844a1aSMatthew Knepley - s2 - the second PetscSection 220*ea844a1aSMatthew Knepley 221*ea844a1aSMatthew Knepley Output Parameter: 222*ea844a1aSMatthew Knepley . congruent - PETSC_TRUE if the two sections are congruent, PETSC_FALSE otherwise 223*ea844a1aSMatthew Knepley 224*ea844a1aSMatthew Knepley Level: intermediate 225*ea844a1aSMatthew Knepley 226*ea844a1aSMatthew Knepley Notes: 227*ea844a1aSMatthew Knepley Field names are disregarded. 228*ea844a1aSMatthew Knepley 229*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate(), PetscSectionCopy(), PetscSectionClone() 230*ea844a1aSMatthew Knepley @*/ 231*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCompare(PetscSection s1, PetscSection s2, PetscBool *congruent) 232*ea844a1aSMatthew Knepley { 233*ea844a1aSMatthew Knepley PetscInt pStart, pEnd, nfields, ncdof, nfcdof, p, f, n1, n2; 234*ea844a1aSMatthew Knepley const PetscInt *idx1, *idx2; 235*ea844a1aSMatthew Knepley IS perm1, perm2; 236*ea844a1aSMatthew Knepley PetscBool flg; 237*ea844a1aSMatthew Knepley PetscMPIInt mflg; 238*ea844a1aSMatthew Knepley PetscErrorCode ierr; 239*ea844a1aSMatthew Knepley 240*ea844a1aSMatthew Knepley PetscFunctionBegin; 241*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s1, PETSC_SECTION_CLASSID, 1); 242*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s2, PETSC_SECTION_CLASSID, 2); 243*ea844a1aSMatthew Knepley PetscValidIntPointer(congruent,3); 244*ea844a1aSMatthew Knepley flg = PETSC_FALSE; 245*ea844a1aSMatthew Knepley 246*ea844a1aSMatthew Knepley ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)s1),PetscObjectComm((PetscObject)s2),&mflg);CHKERRQ(ierr); 247*ea844a1aSMatthew Knepley if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) { 248*ea844a1aSMatthew Knepley *congruent = PETSC_FALSE; 249*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 250*ea844a1aSMatthew Knepley } 251*ea844a1aSMatthew Knepley 252*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s1, &pStart, &pEnd);CHKERRQ(ierr); 253*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s2, &n1, &n2);CHKERRQ(ierr); 254*ea844a1aSMatthew Knepley if (pStart != n1 || pEnd != n2) goto not_congruent; 255*ea844a1aSMatthew Knepley 256*ea844a1aSMatthew Knepley ierr = PetscSectionGetPermutation(s1, &perm1);CHKERRQ(ierr); 257*ea844a1aSMatthew Knepley ierr = PetscSectionGetPermutation(s2, &perm2);CHKERRQ(ierr); 258*ea844a1aSMatthew Knepley if (perm1 && perm2) { 259*ea844a1aSMatthew Knepley ierr = ISEqual(perm1, perm2, congruent);CHKERRQ(ierr); 260*ea844a1aSMatthew Knepley if (!(*congruent)) goto not_congruent; 261*ea844a1aSMatthew Knepley } else if (perm1 != perm2) goto not_congruent; 262*ea844a1aSMatthew Knepley 263*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 264*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s1, p, &n1);CHKERRQ(ierr); 265*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s2, p, &n2);CHKERRQ(ierr); 266*ea844a1aSMatthew Knepley if (n1 != n2) goto not_congruent; 267*ea844a1aSMatthew Knepley 268*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s1, p, &n1);CHKERRQ(ierr); 269*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s2, p, &n2);CHKERRQ(ierr); 270*ea844a1aSMatthew Knepley if (n1 != n2) goto not_congruent; 271*ea844a1aSMatthew Knepley 272*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s1, p, &ncdof);CHKERRQ(ierr); 273*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s2, p, &n2);CHKERRQ(ierr); 274*ea844a1aSMatthew Knepley if (ncdof != n2) goto not_congruent; 275*ea844a1aSMatthew Knepley 276*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s1, p, &idx1);CHKERRQ(ierr); 277*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s2, p, &idx2);CHKERRQ(ierr); 278*ea844a1aSMatthew Knepley ierr = PetscArraycmp(idx1, idx2, ncdof, congruent);CHKERRQ(ierr); 279*ea844a1aSMatthew Knepley if (!(*congruent)) goto not_congruent; 280*ea844a1aSMatthew Knepley } 281*ea844a1aSMatthew Knepley 282*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s1, &nfields);CHKERRQ(ierr); 283*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s2, &n2);CHKERRQ(ierr); 284*ea844a1aSMatthew Knepley if (nfields != n2) goto not_congruent; 285*ea844a1aSMatthew Knepley 286*ea844a1aSMatthew Knepley for (f = 0; f < nfields; ++f) { 287*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s1, f, &n1);CHKERRQ(ierr); 288*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s2, f, &n2);CHKERRQ(ierr); 289*ea844a1aSMatthew Knepley if (n1 != n2) goto not_congruent; 290*ea844a1aSMatthew Knepley 291*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 292*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldOffset(s1, p, f, &n1);CHKERRQ(ierr); 293*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldOffset(s2, p, f, &n2);CHKERRQ(ierr); 294*ea844a1aSMatthew Knepley if (n1 != n2) goto not_congruent; 295*ea844a1aSMatthew Knepley 296*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s1, p, f, &n1);CHKERRQ(ierr); 297*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s2, p, f, &n2);CHKERRQ(ierr); 298*ea844a1aSMatthew Knepley if (n1 != n2) goto not_congruent; 299*ea844a1aSMatthew Knepley 300*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s1, p, f, &nfcdof);CHKERRQ(ierr); 301*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s2, p, f, &n2);CHKERRQ(ierr); 302*ea844a1aSMatthew Knepley if (nfcdof != n2) goto not_congruent; 303*ea844a1aSMatthew Knepley 304*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s1, p, f, &idx1);CHKERRQ(ierr); 305*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s2, p, f, &idx2);CHKERRQ(ierr); 306*ea844a1aSMatthew Knepley ierr = PetscArraycmp(idx1, idx2, nfcdof, congruent);CHKERRQ(ierr); 307*ea844a1aSMatthew Knepley if (!(*congruent)) goto not_congruent; 308*ea844a1aSMatthew Knepley } 309*ea844a1aSMatthew Knepley } 310*ea844a1aSMatthew Knepley 311*ea844a1aSMatthew Knepley flg = PETSC_TRUE; 312*ea844a1aSMatthew Knepley not_congruent: 313*ea844a1aSMatthew Knepley ierr = MPIU_Allreduce(&flg,congruent,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)s1));CHKERRQ(ierr); 314*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 315*ea844a1aSMatthew Knepley } 316*ea844a1aSMatthew Knepley 317*ea844a1aSMatthew Knepley /*@ 318*ea844a1aSMatthew Knepley PetscSectionGetNumFields - Returns the number of fields, or 0 if no fields were defined. 319*ea844a1aSMatthew Knepley 320*ea844a1aSMatthew Knepley Not collective 321*ea844a1aSMatthew Knepley 322*ea844a1aSMatthew Knepley Input Parameter: 323*ea844a1aSMatthew Knepley . s - the PetscSection 324*ea844a1aSMatthew Knepley 325*ea844a1aSMatthew Knepley Output Parameter: 326*ea844a1aSMatthew Knepley . numFields - the number of fields defined, or 0 if none were defined 327*ea844a1aSMatthew Knepley 328*ea844a1aSMatthew Knepley Level: intermediate 329*ea844a1aSMatthew Knepley 330*ea844a1aSMatthew Knepley .seealso: PetscSectionSetNumFields() 331*ea844a1aSMatthew Knepley @*/ 332*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetNumFields(PetscSection s, PetscInt *numFields) 333*ea844a1aSMatthew Knepley { 334*ea844a1aSMatthew Knepley PetscFunctionBegin; 335*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 336*ea844a1aSMatthew Knepley PetscValidPointer(numFields,2); 337*ea844a1aSMatthew Knepley *numFields = s->numFields; 338*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 339*ea844a1aSMatthew Knepley } 340*ea844a1aSMatthew Knepley 341*ea844a1aSMatthew Knepley /*@ 342*ea844a1aSMatthew Knepley PetscSectionSetNumFields - Sets the number of fields. 343*ea844a1aSMatthew Knepley 344*ea844a1aSMatthew Knepley Not collective 345*ea844a1aSMatthew Knepley 346*ea844a1aSMatthew Knepley Input Parameters: 347*ea844a1aSMatthew Knepley + s - the PetscSection 348*ea844a1aSMatthew Knepley - numFields - the number of fields 349*ea844a1aSMatthew Knepley 350*ea844a1aSMatthew Knepley Level: intermediate 351*ea844a1aSMatthew Knepley 352*ea844a1aSMatthew Knepley .seealso: PetscSectionGetNumFields() 353*ea844a1aSMatthew Knepley @*/ 354*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetNumFields(PetscSection s, PetscInt numFields) 355*ea844a1aSMatthew Knepley { 356*ea844a1aSMatthew Knepley PetscInt f; 357*ea844a1aSMatthew Knepley PetscErrorCode ierr; 358*ea844a1aSMatthew Knepley 359*ea844a1aSMatthew Knepley PetscFunctionBegin; 360*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 361*ea844a1aSMatthew Knepley if (numFields <= 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "The number of fields %D must be positive", numFields); 362*ea844a1aSMatthew Knepley ierr = PetscSectionReset(s);CHKERRQ(ierr); 363*ea844a1aSMatthew Knepley 364*ea844a1aSMatthew Knepley s->numFields = numFields; 365*ea844a1aSMatthew Knepley ierr = PetscMalloc1(s->numFields, &s->numFieldComponents);CHKERRQ(ierr); 366*ea844a1aSMatthew Knepley ierr = PetscMalloc1(s->numFields, &s->fieldNames);CHKERRQ(ierr); 367*ea844a1aSMatthew Knepley ierr = PetscMalloc1(s->numFields, &s->field);CHKERRQ(ierr); 368*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) { 369*ea844a1aSMatthew Knepley char name[64]; 370*ea844a1aSMatthew Knepley 371*ea844a1aSMatthew Knepley s->numFieldComponents[f] = 1; 372*ea844a1aSMatthew Knepley 373*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), &s->field[f]);CHKERRQ(ierr); 374*ea844a1aSMatthew Knepley ierr = PetscSNPrintf(name, 64, "Field_%D", f);CHKERRQ(ierr); 375*ea844a1aSMatthew Knepley ierr = PetscStrallocpy(name, (char **) &s->fieldNames[f]);CHKERRQ(ierr); 376*ea844a1aSMatthew Knepley } 377*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 378*ea844a1aSMatthew Knepley } 379*ea844a1aSMatthew Knepley 380*ea844a1aSMatthew Knepley /*@C 381*ea844a1aSMatthew Knepley PetscSectionGetFieldName - Returns the name of a field in the PetscSection 382*ea844a1aSMatthew Knepley 383*ea844a1aSMatthew Knepley Not Collective 384*ea844a1aSMatthew Knepley 385*ea844a1aSMatthew Knepley Input Parameters: 386*ea844a1aSMatthew Knepley + s - the PetscSection 387*ea844a1aSMatthew Knepley - field - the field number 388*ea844a1aSMatthew Knepley 389*ea844a1aSMatthew Knepley Output Parameter: 390*ea844a1aSMatthew Knepley . fieldName - the field name 391*ea844a1aSMatthew Knepley 392*ea844a1aSMatthew Knepley Level: intermediate 393*ea844a1aSMatthew Knepley 394*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldName() 395*ea844a1aSMatthew Knepley @*/ 396*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldName(PetscSection s, PetscInt field, const char *fieldName[]) 397*ea844a1aSMatthew Knepley { 398*ea844a1aSMatthew Knepley PetscFunctionBegin; 399*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 400*ea844a1aSMatthew Knepley PetscValidPointer(fieldName,3); 401*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 402*ea844a1aSMatthew Knepley *fieldName = s->fieldNames[field]; 403*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 404*ea844a1aSMatthew Knepley } 405*ea844a1aSMatthew Knepley 406*ea844a1aSMatthew Knepley /*@C 407*ea844a1aSMatthew Knepley PetscSectionSetFieldName - Sets the name of a field in the PetscSection 408*ea844a1aSMatthew Knepley 409*ea844a1aSMatthew Knepley Not Collective 410*ea844a1aSMatthew Knepley 411*ea844a1aSMatthew Knepley Input Parameters: 412*ea844a1aSMatthew Knepley + s - the PetscSection 413*ea844a1aSMatthew Knepley . field - the field number 414*ea844a1aSMatthew Knepley - fieldName - the field name 415*ea844a1aSMatthew Knepley 416*ea844a1aSMatthew Knepley Level: intermediate 417*ea844a1aSMatthew Knepley 418*ea844a1aSMatthew Knepley .seealso: PetscSectionGetFieldName() 419*ea844a1aSMatthew Knepley @*/ 420*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldName(PetscSection s, PetscInt field, const char fieldName[]) 421*ea844a1aSMatthew Knepley { 422*ea844a1aSMatthew Knepley PetscErrorCode ierr; 423*ea844a1aSMatthew Knepley 424*ea844a1aSMatthew Knepley PetscFunctionBegin; 425*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 426*ea844a1aSMatthew Knepley if (fieldName) PetscValidCharPointer(fieldName,3); 427*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 428*ea844a1aSMatthew Knepley ierr = PetscFree(s->fieldNames[field]);CHKERRQ(ierr); 429*ea844a1aSMatthew Knepley ierr = PetscStrallocpy(fieldName, (char**) &s->fieldNames[field]);CHKERRQ(ierr); 430*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 431*ea844a1aSMatthew Knepley } 432*ea844a1aSMatthew Knepley 433*ea844a1aSMatthew Knepley /*@ 434*ea844a1aSMatthew Knepley PetscSectionGetFieldComponents - Returns the number of field components for the given field. 435*ea844a1aSMatthew Knepley 436*ea844a1aSMatthew Knepley Not collective 437*ea844a1aSMatthew Knepley 438*ea844a1aSMatthew Knepley Input Parameters: 439*ea844a1aSMatthew Knepley + s - the PetscSection 440*ea844a1aSMatthew Knepley - field - the field number 441*ea844a1aSMatthew Knepley 442*ea844a1aSMatthew Knepley Output Parameter: 443*ea844a1aSMatthew Knepley . numComp - the number of field components 444*ea844a1aSMatthew Knepley 445*ea844a1aSMatthew Knepley Level: intermediate 446*ea844a1aSMatthew Knepley 447*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldComponents(), PetscSectionGetNumFields() 448*ea844a1aSMatthew Knepley @*/ 449*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldComponents(PetscSection s, PetscInt field, PetscInt *numComp) 450*ea844a1aSMatthew Knepley { 451*ea844a1aSMatthew Knepley PetscFunctionBegin; 452*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 453*ea844a1aSMatthew Knepley PetscValidPointer(numComp, 3); 454*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 455*ea844a1aSMatthew Knepley *numComp = s->numFieldComponents[field]; 456*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 457*ea844a1aSMatthew Knepley } 458*ea844a1aSMatthew Knepley 459*ea844a1aSMatthew Knepley /*@ 460*ea844a1aSMatthew Knepley PetscSectionSetFieldComponents - Sets the number of field components for the given field. 461*ea844a1aSMatthew Knepley 462*ea844a1aSMatthew Knepley Not collective 463*ea844a1aSMatthew Knepley 464*ea844a1aSMatthew Knepley Input Parameters: 465*ea844a1aSMatthew Knepley + s - the PetscSection 466*ea844a1aSMatthew Knepley . field - the field number 467*ea844a1aSMatthew Knepley - numComp - the number of field components 468*ea844a1aSMatthew Knepley 469*ea844a1aSMatthew Knepley Level: intermediate 470*ea844a1aSMatthew Knepley 471*ea844a1aSMatthew Knepley .seealso: PetscSectionGetNumFieldComponents(), PetscSectionGetNumFields() 472*ea844a1aSMatthew Knepley @*/ 473*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldComponents(PetscSection s, PetscInt field, PetscInt numComp) 474*ea844a1aSMatthew Knepley { 475*ea844a1aSMatthew Knepley PetscFunctionBegin; 476*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 477*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 478*ea844a1aSMatthew Knepley s->numFieldComponents[field] = numComp; 479*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 480*ea844a1aSMatthew Knepley } 481*ea844a1aSMatthew Knepley 482*ea844a1aSMatthew Knepley static PetscErrorCode PetscSectionCheckConstraints_Static(PetscSection s) 483*ea844a1aSMatthew Knepley { 484*ea844a1aSMatthew Knepley PetscErrorCode ierr; 485*ea844a1aSMatthew Knepley 486*ea844a1aSMatthew Knepley PetscFunctionBegin; 487*ea844a1aSMatthew Knepley if (!s->bc) { 488*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s->bc);CHKERRQ(ierr); 489*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(s->bc, s->pStart, s->pEnd);CHKERRQ(ierr); 490*ea844a1aSMatthew Knepley } 491*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 492*ea844a1aSMatthew Knepley } 493*ea844a1aSMatthew Knepley 494*ea844a1aSMatthew Knepley /*@ 495*ea844a1aSMatthew Knepley PetscSectionGetChart - Returns the range [pStart, pEnd) in which points lie. 496*ea844a1aSMatthew Knepley 497*ea844a1aSMatthew Knepley Not collective 498*ea844a1aSMatthew Knepley 499*ea844a1aSMatthew Knepley Input Parameter: 500*ea844a1aSMatthew Knepley . s - the PetscSection 501*ea844a1aSMatthew Knepley 502*ea844a1aSMatthew Knepley Output Parameters: 503*ea844a1aSMatthew Knepley + pStart - the first point 504*ea844a1aSMatthew Knepley - pEnd - one past the last point 505*ea844a1aSMatthew Knepley 506*ea844a1aSMatthew Knepley Level: intermediate 507*ea844a1aSMatthew Knepley 508*ea844a1aSMatthew Knepley .seealso: PetscSectionSetChart(), PetscSectionCreate() 509*ea844a1aSMatthew Knepley @*/ 510*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetChart(PetscSection s, PetscInt *pStart, PetscInt *pEnd) 511*ea844a1aSMatthew Knepley { 512*ea844a1aSMatthew Knepley PetscFunctionBegin; 513*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 514*ea844a1aSMatthew Knepley if (pStart) *pStart = s->pStart; 515*ea844a1aSMatthew Knepley if (pEnd) *pEnd = s->pEnd; 516*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 517*ea844a1aSMatthew Knepley } 518*ea844a1aSMatthew Knepley 519*ea844a1aSMatthew Knepley /*@ 520*ea844a1aSMatthew Knepley PetscSectionSetChart - Sets the range [pStart, pEnd) in which points lie. 521*ea844a1aSMatthew Knepley 522*ea844a1aSMatthew Knepley Not collective 523*ea844a1aSMatthew Knepley 524*ea844a1aSMatthew Knepley Input Parameters: 525*ea844a1aSMatthew Knepley + s - the PetscSection 526*ea844a1aSMatthew Knepley . pStart - the first point 527*ea844a1aSMatthew Knepley - pEnd - one past the last point 528*ea844a1aSMatthew Knepley 529*ea844a1aSMatthew Knepley Level: intermediate 530*ea844a1aSMatthew Knepley 531*ea844a1aSMatthew Knepley .seealso: PetscSectionGetChart(), PetscSectionCreate() 532*ea844a1aSMatthew Knepley @*/ 533*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetChart(PetscSection s, PetscInt pStart, PetscInt pEnd) 534*ea844a1aSMatthew Knepley { 535*ea844a1aSMatthew Knepley PetscInt f; 536*ea844a1aSMatthew Knepley PetscErrorCode ierr; 537*ea844a1aSMatthew Knepley 538*ea844a1aSMatthew Knepley PetscFunctionBegin; 539*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 540*ea844a1aSMatthew Knepley /* Cannot Reset() because it destroys field information */ 541*ea844a1aSMatthew Knepley s->setup = PETSC_FALSE; 542*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(&s->bc);CHKERRQ(ierr); 543*ea844a1aSMatthew Knepley ierr = PetscFree(s->bcIndices);CHKERRQ(ierr); 544*ea844a1aSMatthew Knepley ierr = PetscFree2(s->atlasDof, s->atlasOff);CHKERRQ(ierr); 545*ea844a1aSMatthew Knepley 546*ea844a1aSMatthew Knepley s->pStart = pStart; 547*ea844a1aSMatthew Knepley s->pEnd = pEnd; 548*ea844a1aSMatthew Knepley ierr = PetscMalloc2((pEnd - pStart), &s->atlasDof, (pEnd - pStart), &s->atlasOff);CHKERRQ(ierr); 549*ea844a1aSMatthew Knepley ierr = PetscArrayzero(s->atlasDof, pEnd - pStart);CHKERRQ(ierr); 550*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) { 551*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(s->field[f], pStart, pEnd);CHKERRQ(ierr); 552*ea844a1aSMatthew Knepley } 553*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 554*ea844a1aSMatthew Knepley } 555*ea844a1aSMatthew Knepley 556*ea844a1aSMatthew Knepley /*@ 557*ea844a1aSMatthew Knepley PetscSectionGetPermutation - Returns the permutation of [0, pEnd-pStart) or NULL 558*ea844a1aSMatthew Knepley 559*ea844a1aSMatthew Knepley Not collective 560*ea844a1aSMatthew Knepley 561*ea844a1aSMatthew Knepley Input Parameter: 562*ea844a1aSMatthew Knepley . s - the PetscSection 563*ea844a1aSMatthew Knepley 564*ea844a1aSMatthew Knepley Output Parameters: 565*ea844a1aSMatthew Knepley . perm - The permutation as an IS 566*ea844a1aSMatthew Knepley 567*ea844a1aSMatthew Knepley Level: intermediate 568*ea844a1aSMatthew Knepley 569*ea844a1aSMatthew Knepley .seealso: PetscSectionSetPermutation(), PetscSectionCreate() 570*ea844a1aSMatthew Knepley @*/ 571*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetPermutation(PetscSection s, IS *perm) 572*ea844a1aSMatthew Knepley { 573*ea844a1aSMatthew Knepley PetscFunctionBegin; 574*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 575*ea844a1aSMatthew Knepley if (perm) {PetscValidPointer(perm, 2); *perm = s->perm;} 576*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 577*ea844a1aSMatthew Knepley } 578*ea844a1aSMatthew Knepley 579*ea844a1aSMatthew Knepley /*@ 580*ea844a1aSMatthew Knepley PetscSectionSetPermutation - Sets the permutation for [0, pEnd-pStart) 581*ea844a1aSMatthew Knepley 582*ea844a1aSMatthew Knepley Not collective 583*ea844a1aSMatthew Knepley 584*ea844a1aSMatthew Knepley Input Parameters: 585*ea844a1aSMatthew Knepley + s - the PetscSection 586*ea844a1aSMatthew Knepley - perm - the permutation of points 587*ea844a1aSMatthew Knepley 588*ea844a1aSMatthew Knepley Level: intermediate 589*ea844a1aSMatthew Knepley 590*ea844a1aSMatthew Knepley .seealso: PetscSectionGetPermutation(), PetscSectionCreate() 591*ea844a1aSMatthew Knepley @*/ 592*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetPermutation(PetscSection s, IS perm) 593*ea844a1aSMatthew Knepley { 594*ea844a1aSMatthew Knepley PetscErrorCode ierr; 595*ea844a1aSMatthew Knepley 596*ea844a1aSMatthew Knepley PetscFunctionBegin; 597*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 598*ea844a1aSMatthew Knepley if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 2); 599*ea844a1aSMatthew Knepley if (s->setup) SETERRQ(PetscObjectComm((PetscObject) s), PETSC_ERR_ARG_WRONGSTATE, "Cannot set a permutation after the section is setup"); 600*ea844a1aSMatthew Knepley if (s->perm != perm) { 601*ea844a1aSMatthew Knepley ierr = ISDestroy(&s->perm);CHKERRQ(ierr); 602*ea844a1aSMatthew Knepley if (perm) { 603*ea844a1aSMatthew Knepley s->perm = perm; 604*ea844a1aSMatthew Knepley ierr = PetscObjectReference((PetscObject) s->perm);CHKERRQ(ierr); 605*ea844a1aSMatthew Knepley } 606*ea844a1aSMatthew Knepley } 607*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 608*ea844a1aSMatthew Knepley } 609*ea844a1aSMatthew Knepley 610*ea844a1aSMatthew Knepley /*@ 611*ea844a1aSMatthew Knepley PetscSectionGetPointMajor - Returns the flag for dof ordering, true if it is point major, otherwise field major 612*ea844a1aSMatthew Knepley 613*ea844a1aSMatthew Knepley Not collective 614*ea844a1aSMatthew Knepley 615*ea844a1aSMatthew Knepley Input Parameter: 616*ea844a1aSMatthew Knepley . s - the PetscSection 617*ea844a1aSMatthew Knepley 618*ea844a1aSMatthew Knepley Output Parameter: 619*ea844a1aSMatthew Knepley . pm - the flag for point major ordering 620*ea844a1aSMatthew Knepley 621*ea844a1aSMatthew Knepley Level: intermediate 622*ea844a1aSMatthew Knepley 623*ea844a1aSMatthew Knepley .seealso: PetscSectionSetPointMajor() 624*ea844a1aSMatthew Knepley @*/ 625*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetPointMajor(PetscSection s, PetscBool *pm) 626*ea844a1aSMatthew Knepley { 627*ea844a1aSMatthew Knepley PetscFunctionBegin; 628*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 629*ea844a1aSMatthew Knepley PetscValidPointer(pm,2); 630*ea844a1aSMatthew Knepley *pm = s->pointMajor; 631*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 632*ea844a1aSMatthew Knepley } 633*ea844a1aSMatthew Knepley 634*ea844a1aSMatthew Knepley /*@ 635*ea844a1aSMatthew Knepley PetscSectionSetPointMajor - Sets the flag for dof ordering, true if it is point major, otherwise field major 636*ea844a1aSMatthew Knepley 637*ea844a1aSMatthew Knepley Not collective 638*ea844a1aSMatthew Knepley 639*ea844a1aSMatthew Knepley Input Parameters: 640*ea844a1aSMatthew Knepley + s - the PetscSection 641*ea844a1aSMatthew Knepley - pm - the flag for point major ordering 642*ea844a1aSMatthew Knepley 643*ea844a1aSMatthew Knepley Not collective 644*ea844a1aSMatthew Knepley 645*ea844a1aSMatthew Knepley Level: intermediate 646*ea844a1aSMatthew Knepley 647*ea844a1aSMatthew Knepley .seealso: PetscSectionGetPointMajor() 648*ea844a1aSMatthew Knepley @*/ 649*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetPointMajor(PetscSection s, PetscBool pm) 650*ea844a1aSMatthew Knepley { 651*ea844a1aSMatthew Knepley PetscFunctionBegin; 652*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 653*ea844a1aSMatthew Knepley if (s->setup) SETERRQ(PetscObjectComm((PetscObject) s), PETSC_ERR_ARG_WRONGSTATE, "Cannot set the dof ordering after the section is setup"); 654*ea844a1aSMatthew Knepley s->pointMajor = pm; 655*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 656*ea844a1aSMatthew Knepley } 657*ea844a1aSMatthew Knepley 658*ea844a1aSMatthew Knepley /*@ 659*ea844a1aSMatthew Knepley PetscSectionGetDof - Return the number of degrees of freedom associated with a given point. 660*ea844a1aSMatthew Knepley 661*ea844a1aSMatthew Knepley Not collective 662*ea844a1aSMatthew Knepley 663*ea844a1aSMatthew Knepley Input Parameters: 664*ea844a1aSMatthew Knepley + s - the PetscSection 665*ea844a1aSMatthew Knepley - point - the point 666*ea844a1aSMatthew Knepley 667*ea844a1aSMatthew Knepley Output Parameter: 668*ea844a1aSMatthew Knepley . numDof - the number of dof 669*ea844a1aSMatthew Knepley 670*ea844a1aSMatthew Knepley Level: intermediate 671*ea844a1aSMatthew Knepley 672*ea844a1aSMatthew Knepley .seealso: PetscSectionSetDof(), PetscSectionCreate() 673*ea844a1aSMatthew Knepley @*/ 674*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetDof(PetscSection s, PetscInt point, PetscInt *numDof) 675*ea844a1aSMatthew Knepley { 676*ea844a1aSMatthew Knepley PetscFunctionBegin; 677*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 678*ea844a1aSMatthew Knepley PetscValidPointer(numDof, 3); 679*ea844a1aSMatthew Knepley #if defined(PETSC_USE_DEBUG) 680*ea844a1aSMatthew Knepley if ((point < s->pStart) || (point >= s->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %D should be in [%D, %D)", point, s->pStart, s->pEnd); 681*ea844a1aSMatthew Knepley #endif 682*ea844a1aSMatthew Knepley *numDof = s->atlasDof[point - s->pStart]; 683*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 684*ea844a1aSMatthew Knepley } 685*ea844a1aSMatthew Knepley 686*ea844a1aSMatthew Knepley /*@ 687*ea844a1aSMatthew Knepley PetscSectionSetDof - Sets the number of degrees of freedom associated with a given point. 688*ea844a1aSMatthew Knepley 689*ea844a1aSMatthew Knepley Not collective 690*ea844a1aSMatthew Knepley 691*ea844a1aSMatthew Knepley Input Parameters: 692*ea844a1aSMatthew Knepley + s - the PetscSection 693*ea844a1aSMatthew Knepley . point - the point 694*ea844a1aSMatthew Knepley - numDof - the number of dof 695*ea844a1aSMatthew Knepley 696*ea844a1aSMatthew Knepley Level: intermediate 697*ea844a1aSMatthew Knepley 698*ea844a1aSMatthew Knepley .seealso: PetscSectionGetDof(), PetscSectionAddDof(), PetscSectionCreate() 699*ea844a1aSMatthew Knepley @*/ 700*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetDof(PetscSection s, PetscInt point, PetscInt numDof) 701*ea844a1aSMatthew Knepley { 702*ea844a1aSMatthew Knepley PetscFunctionBegin; 703*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 704*ea844a1aSMatthew Knepley if ((point < s->pStart) || (point >= s->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %D should be in [%D, %D)", point, s->pStart, s->pEnd); 705*ea844a1aSMatthew Knepley s->atlasDof[point - s->pStart] = numDof; 706*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 707*ea844a1aSMatthew Knepley } 708*ea844a1aSMatthew Knepley 709*ea844a1aSMatthew Knepley /*@ 710*ea844a1aSMatthew Knepley PetscSectionAddDof - Adds to the number of degrees of freedom associated with a given point. 711*ea844a1aSMatthew Knepley 712*ea844a1aSMatthew Knepley Not collective 713*ea844a1aSMatthew Knepley 714*ea844a1aSMatthew Knepley Input Parameters: 715*ea844a1aSMatthew Knepley + s - the PetscSection 716*ea844a1aSMatthew Knepley . point - the point 717*ea844a1aSMatthew Knepley - numDof - the number of additional dof 718*ea844a1aSMatthew Knepley 719*ea844a1aSMatthew Knepley Level: intermediate 720*ea844a1aSMatthew Knepley 721*ea844a1aSMatthew Knepley .seealso: PetscSectionGetDof(), PetscSectionSetDof(), PetscSectionCreate() 722*ea844a1aSMatthew Knepley @*/ 723*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionAddDof(PetscSection s, PetscInt point, PetscInt numDof) 724*ea844a1aSMatthew Knepley { 725*ea844a1aSMatthew Knepley PetscFunctionBegin; 726*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 727*ea844a1aSMatthew Knepley #if defined(PETSC_USE_DEBUG) 728*ea844a1aSMatthew Knepley if ((point < s->pStart) || (point >= s->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %D should be in [%D, %D)", point, s->pStart, s->pEnd); 729*ea844a1aSMatthew Knepley #endif 730*ea844a1aSMatthew Knepley s->atlasDof[point - s->pStart] += numDof; 731*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 732*ea844a1aSMatthew Knepley } 733*ea844a1aSMatthew Knepley 734*ea844a1aSMatthew Knepley /*@ 735*ea844a1aSMatthew Knepley PetscSectionGetFieldDof - Return the number of degrees of freedom associated with a field on a given point. 736*ea844a1aSMatthew Knepley 737*ea844a1aSMatthew Knepley Not collective 738*ea844a1aSMatthew Knepley 739*ea844a1aSMatthew Knepley Input Parameters: 740*ea844a1aSMatthew Knepley + s - the PetscSection 741*ea844a1aSMatthew Knepley . point - the point 742*ea844a1aSMatthew Knepley - field - the field 743*ea844a1aSMatthew Knepley 744*ea844a1aSMatthew Knepley Output Parameter: 745*ea844a1aSMatthew Knepley . numDof - the number of dof 746*ea844a1aSMatthew Knepley 747*ea844a1aSMatthew Knepley Level: intermediate 748*ea844a1aSMatthew Knepley 749*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldDof(), PetscSectionCreate() 750*ea844a1aSMatthew Knepley @*/ 751*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt *numDof) 752*ea844a1aSMatthew Knepley { 753*ea844a1aSMatthew Knepley PetscErrorCode ierr; 754*ea844a1aSMatthew Knepley 755*ea844a1aSMatthew Knepley PetscFunctionBegin; 756*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 757*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 758*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s->field[field], point, numDof);CHKERRQ(ierr); 759*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 760*ea844a1aSMatthew Knepley } 761*ea844a1aSMatthew Knepley 762*ea844a1aSMatthew Knepley /*@ 763*ea844a1aSMatthew Knepley PetscSectionSetFieldDof - Sets the number of degrees of freedom associated with a field on a given point. 764*ea844a1aSMatthew Knepley 765*ea844a1aSMatthew Knepley Not collective 766*ea844a1aSMatthew Knepley 767*ea844a1aSMatthew Knepley Input Parameters: 768*ea844a1aSMatthew Knepley + s - the PetscSection 769*ea844a1aSMatthew Knepley . point - the point 770*ea844a1aSMatthew Knepley . field - the field 771*ea844a1aSMatthew Knepley - numDof - the number of dof 772*ea844a1aSMatthew Knepley 773*ea844a1aSMatthew Knepley Level: intermediate 774*ea844a1aSMatthew Knepley 775*ea844a1aSMatthew Knepley .seealso: PetscSectionGetFieldDof(), PetscSectionCreate() 776*ea844a1aSMatthew Knepley @*/ 777*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) 778*ea844a1aSMatthew Knepley { 779*ea844a1aSMatthew Knepley PetscErrorCode ierr; 780*ea844a1aSMatthew Knepley 781*ea844a1aSMatthew Knepley PetscFunctionBegin; 782*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 783*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 784*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(s->field[field], point, numDof);CHKERRQ(ierr); 785*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 786*ea844a1aSMatthew Knepley } 787*ea844a1aSMatthew Knepley 788*ea844a1aSMatthew Knepley /*@ 789*ea844a1aSMatthew Knepley PetscSectionAddFieldDof - Adds a number of degrees of freedom associated with a field on a given point. 790*ea844a1aSMatthew Knepley 791*ea844a1aSMatthew Knepley Not collective 792*ea844a1aSMatthew Knepley 793*ea844a1aSMatthew Knepley Input Parameters: 794*ea844a1aSMatthew Knepley + s - the PetscSection 795*ea844a1aSMatthew Knepley . point - the point 796*ea844a1aSMatthew Knepley . field - the field 797*ea844a1aSMatthew Knepley - numDof - the number of dof 798*ea844a1aSMatthew Knepley 799*ea844a1aSMatthew Knepley Level: intermediate 800*ea844a1aSMatthew Knepley 801*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldDof(), PetscSectionGetFieldDof(), PetscSectionCreate() 802*ea844a1aSMatthew Knepley @*/ 803*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionAddFieldDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) 804*ea844a1aSMatthew Knepley { 805*ea844a1aSMatthew Knepley PetscErrorCode ierr; 806*ea844a1aSMatthew Knepley 807*ea844a1aSMatthew Knepley PetscFunctionBegin; 808*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 809*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 810*ea844a1aSMatthew Knepley ierr = PetscSectionAddDof(s->field[field], point, numDof);CHKERRQ(ierr); 811*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 812*ea844a1aSMatthew Knepley } 813*ea844a1aSMatthew Knepley 814*ea844a1aSMatthew Knepley /*@ 815*ea844a1aSMatthew Knepley PetscSectionGetConstraintDof - Return the number of constrained degrees of freedom associated with a given point. 816*ea844a1aSMatthew Knepley 817*ea844a1aSMatthew Knepley Not collective 818*ea844a1aSMatthew Knepley 819*ea844a1aSMatthew Knepley Input Parameters: 820*ea844a1aSMatthew Knepley + s - the PetscSection 821*ea844a1aSMatthew Knepley - point - the point 822*ea844a1aSMatthew Knepley 823*ea844a1aSMatthew Knepley Output Parameter: 824*ea844a1aSMatthew Knepley . numDof - the number of dof which are fixed by constraints 825*ea844a1aSMatthew Knepley 826*ea844a1aSMatthew Knepley Level: intermediate 827*ea844a1aSMatthew Knepley 828*ea844a1aSMatthew Knepley .seealso: PetscSectionGetDof(), PetscSectionSetConstraintDof(), PetscSectionCreate() 829*ea844a1aSMatthew Knepley @*/ 830*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetConstraintDof(PetscSection s, PetscInt point, PetscInt *numDof) 831*ea844a1aSMatthew Knepley { 832*ea844a1aSMatthew Knepley PetscErrorCode ierr; 833*ea844a1aSMatthew Knepley 834*ea844a1aSMatthew Knepley PetscFunctionBegin; 835*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 836*ea844a1aSMatthew Knepley PetscValidPointer(numDof, 3); 837*ea844a1aSMatthew Knepley if (s->bc) { 838*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s->bc, point, numDof);CHKERRQ(ierr); 839*ea844a1aSMatthew Knepley } else *numDof = 0; 840*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 841*ea844a1aSMatthew Knepley } 842*ea844a1aSMatthew Knepley 843*ea844a1aSMatthew Knepley /*@ 844*ea844a1aSMatthew Knepley PetscSectionSetConstraintDof - Set the number of constrained degrees of freedom associated with a given point. 845*ea844a1aSMatthew Knepley 846*ea844a1aSMatthew Knepley Not collective 847*ea844a1aSMatthew Knepley 848*ea844a1aSMatthew Knepley Input Parameters: 849*ea844a1aSMatthew Knepley + s - the PetscSection 850*ea844a1aSMatthew Knepley . point - the point 851*ea844a1aSMatthew Knepley - numDof - the number of dof which are fixed by constraints 852*ea844a1aSMatthew Knepley 853*ea844a1aSMatthew Knepley Level: intermediate 854*ea844a1aSMatthew Knepley 855*ea844a1aSMatthew Knepley .seealso: PetscSectionSetDof(), PetscSectionGetConstraintDof(), PetscSectionCreate() 856*ea844a1aSMatthew Knepley @*/ 857*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetConstraintDof(PetscSection s, PetscInt point, PetscInt numDof) 858*ea844a1aSMatthew Knepley { 859*ea844a1aSMatthew Knepley PetscErrorCode ierr; 860*ea844a1aSMatthew Knepley 861*ea844a1aSMatthew Knepley PetscFunctionBegin; 862*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 863*ea844a1aSMatthew Knepley if (numDof) { 864*ea844a1aSMatthew Knepley ierr = PetscSectionCheckConstraints_Static(s);CHKERRQ(ierr); 865*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(s->bc, point, numDof);CHKERRQ(ierr); 866*ea844a1aSMatthew Knepley } 867*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 868*ea844a1aSMatthew Knepley } 869*ea844a1aSMatthew Knepley 870*ea844a1aSMatthew Knepley /*@ 871*ea844a1aSMatthew Knepley PetscSectionAddConstraintDof - Increment the number of constrained degrees of freedom associated with a given point. 872*ea844a1aSMatthew Knepley 873*ea844a1aSMatthew Knepley Not collective 874*ea844a1aSMatthew Knepley 875*ea844a1aSMatthew Knepley Input Parameters: 876*ea844a1aSMatthew Knepley + s - the PetscSection 877*ea844a1aSMatthew Knepley . point - the point 878*ea844a1aSMatthew Knepley - numDof - the number of additional dof which are fixed by constraints 879*ea844a1aSMatthew Knepley 880*ea844a1aSMatthew Knepley Level: intermediate 881*ea844a1aSMatthew Knepley 882*ea844a1aSMatthew Knepley .seealso: PetscSectionAddDof(), PetscSectionGetConstraintDof(), PetscSectionCreate() 883*ea844a1aSMatthew Knepley @*/ 884*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionAddConstraintDof(PetscSection s, PetscInt point, PetscInt numDof) 885*ea844a1aSMatthew Knepley { 886*ea844a1aSMatthew Knepley PetscErrorCode ierr; 887*ea844a1aSMatthew Knepley 888*ea844a1aSMatthew Knepley PetscFunctionBegin; 889*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 890*ea844a1aSMatthew Knepley if (numDof) { 891*ea844a1aSMatthew Knepley ierr = PetscSectionCheckConstraints_Static(s);CHKERRQ(ierr); 892*ea844a1aSMatthew Knepley ierr = PetscSectionAddDof(s->bc, point, numDof);CHKERRQ(ierr); 893*ea844a1aSMatthew Knepley } 894*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 895*ea844a1aSMatthew Knepley } 896*ea844a1aSMatthew Knepley 897*ea844a1aSMatthew Knepley /*@ 898*ea844a1aSMatthew Knepley PetscSectionGetFieldConstraintDof - Return the number of constrained degrees of freedom associated with a given field on a point. 899*ea844a1aSMatthew Knepley 900*ea844a1aSMatthew Knepley Not collective 901*ea844a1aSMatthew Knepley 902*ea844a1aSMatthew Knepley Input Parameters: 903*ea844a1aSMatthew Knepley + s - the PetscSection 904*ea844a1aSMatthew Knepley . point - the point 905*ea844a1aSMatthew Knepley - field - the field 906*ea844a1aSMatthew Knepley 907*ea844a1aSMatthew Knepley Output Parameter: 908*ea844a1aSMatthew Knepley . numDof - the number of dof which are fixed by constraints 909*ea844a1aSMatthew Knepley 910*ea844a1aSMatthew Knepley Level: intermediate 911*ea844a1aSMatthew Knepley 912*ea844a1aSMatthew Knepley .seealso: PetscSectionGetDof(), PetscSectionSetFieldConstraintDof(), PetscSectionCreate() 913*ea844a1aSMatthew Knepley @*/ 914*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt *numDof) 915*ea844a1aSMatthew Knepley { 916*ea844a1aSMatthew Knepley PetscErrorCode ierr; 917*ea844a1aSMatthew Knepley 918*ea844a1aSMatthew Knepley PetscFunctionBegin; 919*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 920*ea844a1aSMatthew Knepley PetscValidPointer(numDof, 4); 921*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 922*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s->field[field], point, numDof);CHKERRQ(ierr); 923*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 924*ea844a1aSMatthew Knepley } 925*ea844a1aSMatthew Knepley 926*ea844a1aSMatthew Knepley /*@ 927*ea844a1aSMatthew Knepley PetscSectionSetFieldConstraintDof - Set the number of constrained degrees of freedom associated with a given field on a point. 928*ea844a1aSMatthew Knepley 929*ea844a1aSMatthew Knepley Not collective 930*ea844a1aSMatthew Knepley 931*ea844a1aSMatthew Knepley Input Parameters: 932*ea844a1aSMatthew Knepley + s - the PetscSection 933*ea844a1aSMatthew Knepley . point - the point 934*ea844a1aSMatthew Knepley . field - the field 935*ea844a1aSMatthew Knepley - numDof - the number of dof which are fixed by constraints 936*ea844a1aSMatthew Knepley 937*ea844a1aSMatthew Knepley Level: intermediate 938*ea844a1aSMatthew Knepley 939*ea844a1aSMatthew Knepley .seealso: PetscSectionSetDof(), PetscSectionGetFieldConstraintDof(), PetscSectionCreate() 940*ea844a1aSMatthew Knepley @*/ 941*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) 942*ea844a1aSMatthew Knepley { 943*ea844a1aSMatthew Knepley PetscErrorCode ierr; 944*ea844a1aSMatthew Knepley 945*ea844a1aSMatthew Knepley PetscFunctionBegin; 946*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 947*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 948*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintDof(s->field[field], point, numDof);CHKERRQ(ierr); 949*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 950*ea844a1aSMatthew Knepley } 951*ea844a1aSMatthew Knepley 952*ea844a1aSMatthew Knepley /*@ 953*ea844a1aSMatthew Knepley PetscSectionAddFieldConstraintDof - Increment the number of constrained degrees of freedom associated with a given field on a point. 954*ea844a1aSMatthew Knepley 955*ea844a1aSMatthew Knepley Not collective 956*ea844a1aSMatthew Knepley 957*ea844a1aSMatthew Knepley Input Parameters: 958*ea844a1aSMatthew Knepley + s - the PetscSection 959*ea844a1aSMatthew Knepley . point - the point 960*ea844a1aSMatthew Knepley . field - the field 961*ea844a1aSMatthew Knepley - numDof - the number of additional dof which are fixed by constraints 962*ea844a1aSMatthew Knepley 963*ea844a1aSMatthew Knepley Level: intermediate 964*ea844a1aSMatthew Knepley 965*ea844a1aSMatthew Knepley .seealso: PetscSectionAddDof(), PetscSectionGetFieldConstraintDof(), PetscSectionCreate() 966*ea844a1aSMatthew Knepley @*/ 967*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionAddFieldConstraintDof(PetscSection s, PetscInt point, PetscInt field, PetscInt numDof) 968*ea844a1aSMatthew Knepley { 969*ea844a1aSMatthew Knepley PetscErrorCode ierr; 970*ea844a1aSMatthew Knepley 971*ea844a1aSMatthew Knepley PetscFunctionBegin; 972*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 973*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 974*ea844a1aSMatthew Knepley ierr = PetscSectionAddConstraintDof(s->field[field], point, numDof);CHKERRQ(ierr); 975*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 976*ea844a1aSMatthew Knepley } 977*ea844a1aSMatthew Knepley 978*ea844a1aSMatthew Knepley /*@ 979*ea844a1aSMatthew Knepley PetscSectionSetUpBC - Setup the subsections describing boundary conditions. 980*ea844a1aSMatthew Knepley 981*ea844a1aSMatthew Knepley Not collective 982*ea844a1aSMatthew Knepley 983*ea844a1aSMatthew Knepley Input Parameter: 984*ea844a1aSMatthew Knepley . s - the PetscSection 985*ea844a1aSMatthew Knepley 986*ea844a1aSMatthew Knepley Level: advanced 987*ea844a1aSMatthew Knepley 988*ea844a1aSMatthew Knepley .seealso: PetscSectionSetUp(), PetscSectionCreate() 989*ea844a1aSMatthew Knepley @*/ 990*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetUpBC(PetscSection s) 991*ea844a1aSMatthew Knepley { 992*ea844a1aSMatthew Knepley PetscErrorCode ierr; 993*ea844a1aSMatthew Knepley 994*ea844a1aSMatthew Knepley PetscFunctionBegin; 995*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 996*ea844a1aSMatthew Knepley if (s->bc) { 997*ea844a1aSMatthew Knepley const PetscInt last = (s->bc->pEnd-s->bc->pStart) - 1; 998*ea844a1aSMatthew Knepley 999*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(s->bc);CHKERRQ(ierr); 1000*ea844a1aSMatthew Knepley ierr = PetscMalloc1(s->bc->atlasOff[last] + s->bc->atlasDof[last], &s->bcIndices);CHKERRQ(ierr); 1001*ea844a1aSMatthew Knepley } 1002*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1003*ea844a1aSMatthew Knepley } 1004*ea844a1aSMatthew Knepley 1005*ea844a1aSMatthew Knepley /*@ 1006*ea844a1aSMatthew Knepley PetscSectionSetUp - Calculate offsets based upon the number of degrees of freedom for each point. 1007*ea844a1aSMatthew Knepley 1008*ea844a1aSMatthew Knepley Not collective 1009*ea844a1aSMatthew Knepley 1010*ea844a1aSMatthew Knepley Input Parameter: 1011*ea844a1aSMatthew Knepley . s - the PetscSection 1012*ea844a1aSMatthew Knepley 1013*ea844a1aSMatthew Knepley Level: intermediate 1014*ea844a1aSMatthew Knepley 1015*ea844a1aSMatthew Knepley .seealso: PetscSectionCreate() 1016*ea844a1aSMatthew Knepley @*/ 1017*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetUp(PetscSection s) 1018*ea844a1aSMatthew Knepley { 1019*ea844a1aSMatthew Knepley const PetscInt *pind = NULL; 1020*ea844a1aSMatthew Knepley PetscInt offset = 0, foff, p, f; 1021*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1022*ea844a1aSMatthew Knepley 1023*ea844a1aSMatthew Knepley PetscFunctionBegin; 1024*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1025*ea844a1aSMatthew Knepley if (s->setup) PetscFunctionReturn(0); 1026*ea844a1aSMatthew Knepley s->setup = PETSC_TRUE; 1027*ea844a1aSMatthew Knepley /* Set offsets and field offsets for all points */ 1028*ea844a1aSMatthew Knepley /* Assume that all fields have the same chart */ 1029*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISGetIndices(s->perm, &pind);CHKERRQ(ierr);} 1030*ea844a1aSMatthew Knepley if (s->pointMajor) { 1031*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) { 1032*ea844a1aSMatthew Knepley const PetscInt q = pind ? pind[p] : p; 1033*ea844a1aSMatthew Knepley 1034*ea844a1aSMatthew Knepley /* Set point offset */ 1035*ea844a1aSMatthew Knepley s->atlasOff[q] = offset; 1036*ea844a1aSMatthew Knepley offset += s->atlasDof[q]; 1037*ea844a1aSMatthew Knepley s->maxDof = PetscMax(s->maxDof, s->atlasDof[q]); 1038*ea844a1aSMatthew Knepley /* Set field offset */ 1039*ea844a1aSMatthew Knepley for (f = 0, foff = s->atlasOff[q]; f < s->numFields; ++f) { 1040*ea844a1aSMatthew Knepley PetscSection sf = s->field[f]; 1041*ea844a1aSMatthew Knepley 1042*ea844a1aSMatthew Knepley sf->atlasOff[q] = foff; 1043*ea844a1aSMatthew Knepley foff += sf->atlasDof[q]; 1044*ea844a1aSMatthew Knepley } 1045*ea844a1aSMatthew Knepley } 1046*ea844a1aSMatthew Knepley } else { 1047*ea844a1aSMatthew Knepley /* Set field offsets for all points */ 1048*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) { 1049*ea844a1aSMatthew Knepley PetscSection sf = s->field[f]; 1050*ea844a1aSMatthew Knepley 1051*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) { 1052*ea844a1aSMatthew Knepley const PetscInt q = pind ? pind[p] : p; 1053*ea844a1aSMatthew Knepley 1054*ea844a1aSMatthew Knepley sf->atlasOff[q] = offset; 1055*ea844a1aSMatthew Knepley offset += sf->atlasDof[q]; 1056*ea844a1aSMatthew Knepley } 1057*ea844a1aSMatthew Knepley } 1058*ea844a1aSMatthew Knepley /* Disable point offsets since these are unused */ 1059*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) { 1060*ea844a1aSMatthew Knepley s->atlasOff[p] = -1; 1061*ea844a1aSMatthew Knepley s->maxDof = PetscMax(s->maxDof, s->atlasDof[p]); 1062*ea844a1aSMatthew Knepley } 1063*ea844a1aSMatthew Knepley } 1064*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISRestoreIndices(s->perm, &pind);CHKERRQ(ierr);} 1065*ea844a1aSMatthew Knepley /* Setup BC sections */ 1066*ea844a1aSMatthew Knepley ierr = PetscSectionSetUpBC(s);CHKERRQ(ierr); 1067*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) {ierr = PetscSectionSetUpBC(s->field[f]);CHKERRQ(ierr);} 1068*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1069*ea844a1aSMatthew Knepley } 1070*ea844a1aSMatthew Knepley 1071*ea844a1aSMatthew Knepley /*@ 1072*ea844a1aSMatthew Knepley PetscSectionGetMaxDof - Return the maximum number of degrees of freedom on any point in the chart 1073*ea844a1aSMatthew Knepley 1074*ea844a1aSMatthew Knepley Not collective 1075*ea844a1aSMatthew Knepley 1076*ea844a1aSMatthew Knepley Input Parameters: 1077*ea844a1aSMatthew Knepley . s - the PetscSection 1078*ea844a1aSMatthew Knepley 1079*ea844a1aSMatthew Knepley Output Parameter: 1080*ea844a1aSMatthew Knepley . maxDof - the maximum dof 1081*ea844a1aSMatthew Knepley 1082*ea844a1aSMatthew Knepley Level: intermediate 1083*ea844a1aSMatthew Knepley 1084*ea844a1aSMatthew Knepley .seealso: PetscSectionGetDof(), PetscSectionSetDof(), PetscSectionCreate() 1085*ea844a1aSMatthew Knepley @*/ 1086*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetMaxDof(PetscSection s, PetscInt *maxDof) 1087*ea844a1aSMatthew Knepley { 1088*ea844a1aSMatthew Knepley PetscFunctionBegin; 1089*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1090*ea844a1aSMatthew Knepley PetscValidPointer(maxDof, 2); 1091*ea844a1aSMatthew Knepley *maxDof = s->maxDof; 1092*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1093*ea844a1aSMatthew Knepley } 1094*ea844a1aSMatthew Knepley 1095*ea844a1aSMatthew Knepley /*@ 1096*ea844a1aSMatthew Knepley PetscSectionGetStorageSize - Return the size of an array or local Vec capable of holding all the degrees of freedom. 1097*ea844a1aSMatthew Knepley 1098*ea844a1aSMatthew Knepley Not collective 1099*ea844a1aSMatthew Knepley 1100*ea844a1aSMatthew Knepley Input Parameter: 1101*ea844a1aSMatthew Knepley . s - the PetscSection 1102*ea844a1aSMatthew Knepley 1103*ea844a1aSMatthew Knepley Output Parameter: 1104*ea844a1aSMatthew Knepley . size - the size of an array which can hold all the dofs 1105*ea844a1aSMatthew Knepley 1106*ea844a1aSMatthew Knepley Level: intermediate 1107*ea844a1aSMatthew Knepley 1108*ea844a1aSMatthew Knepley .seealso: PetscSectionGetOffset(), PetscSectionGetConstrainedStorageSize(), PetscSectionCreate() 1109*ea844a1aSMatthew Knepley @*/ 1110*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetStorageSize(PetscSection s, PetscInt *size) 1111*ea844a1aSMatthew Knepley { 1112*ea844a1aSMatthew Knepley PetscInt p, n = 0; 1113*ea844a1aSMatthew Knepley 1114*ea844a1aSMatthew Knepley PetscFunctionBegin; 1115*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1116*ea844a1aSMatthew Knepley PetscValidPointer(size, 2); 1117*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) n += s->atlasDof[p] > 0 ? s->atlasDof[p] : 0; 1118*ea844a1aSMatthew Knepley *size = n; 1119*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1120*ea844a1aSMatthew Knepley } 1121*ea844a1aSMatthew Knepley 1122*ea844a1aSMatthew Knepley /*@ 1123*ea844a1aSMatthew Knepley PetscSectionGetConstrainedStorageSize - Return the size of an array or local Vec capable of holding all unconstrained degrees of freedom. 1124*ea844a1aSMatthew Knepley 1125*ea844a1aSMatthew Knepley Not collective 1126*ea844a1aSMatthew Knepley 1127*ea844a1aSMatthew Knepley Input Parameters: 1128*ea844a1aSMatthew Knepley + s - the PetscSection 1129*ea844a1aSMatthew Knepley - point - the point 1130*ea844a1aSMatthew Knepley 1131*ea844a1aSMatthew Knepley Output Parameter: 1132*ea844a1aSMatthew Knepley . size - the size of an array which can hold all unconstrained dofs 1133*ea844a1aSMatthew Knepley 1134*ea844a1aSMatthew Knepley Level: intermediate 1135*ea844a1aSMatthew Knepley 1136*ea844a1aSMatthew Knepley .seealso: PetscSectionGetStorageSize(), PetscSectionGetOffset(), PetscSectionCreate() 1137*ea844a1aSMatthew Knepley @*/ 1138*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetConstrainedStorageSize(PetscSection s, PetscInt *size) 1139*ea844a1aSMatthew Knepley { 1140*ea844a1aSMatthew Knepley PetscInt p, n = 0; 1141*ea844a1aSMatthew Knepley 1142*ea844a1aSMatthew Knepley PetscFunctionBegin; 1143*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1144*ea844a1aSMatthew Knepley PetscValidPointer(size, 2); 1145*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) { 1146*ea844a1aSMatthew Knepley const PetscInt cdof = s->bc ? s->bc->atlasDof[p] : 0; 1147*ea844a1aSMatthew Knepley n += s->atlasDof[p] > 0 ? s->atlasDof[p] - cdof : 0; 1148*ea844a1aSMatthew Knepley } 1149*ea844a1aSMatthew Knepley *size = n; 1150*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1151*ea844a1aSMatthew Knepley } 1152*ea844a1aSMatthew Knepley 1153*ea844a1aSMatthew Knepley /*@ 1154*ea844a1aSMatthew Knepley PetscSectionCreateGlobalSection - Create a section describing the global field layout using 1155*ea844a1aSMatthew Knepley the local section and an SF describing the section point overlap. 1156*ea844a1aSMatthew Knepley 1157*ea844a1aSMatthew Knepley Input Parameters: 1158*ea844a1aSMatthew Knepley + s - The PetscSection for the local field layout 1159*ea844a1aSMatthew Knepley . sf - The SF describing parallel layout of the section points (leaves are unowned local points) 1160*ea844a1aSMatthew Knepley . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1161*ea844a1aSMatthew Knepley - localOffsets - If PETSC_TRUE, use local rather than global offsets for the points 1162*ea844a1aSMatthew Knepley 1163*ea844a1aSMatthew Knepley Output Parameter: 1164*ea844a1aSMatthew Knepley . gsection - The PetscSection for the global field layout 1165*ea844a1aSMatthew Knepley 1166*ea844a1aSMatthew Knepley Note: This gives negative sizes and offsets to points not owned by this process 1167*ea844a1aSMatthew Knepley 1168*ea844a1aSMatthew Knepley Level: intermediate 1169*ea844a1aSMatthew Knepley 1170*ea844a1aSMatthew Knepley .seealso: PetscSectionCreate() 1171*ea844a1aSMatthew Knepley @*/ 1172*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreateGlobalSection(PetscSection s, PetscSF sf, PetscBool includeConstraints, PetscBool localOffsets, PetscSection *gsection) 1173*ea844a1aSMatthew Knepley { 1174*ea844a1aSMatthew Knepley PetscSection gs; 1175*ea844a1aSMatthew Knepley const PetscInt *pind = NULL; 1176*ea844a1aSMatthew Knepley PetscInt *recv = NULL, *neg = NULL; 1177*ea844a1aSMatthew Knepley PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots, nlocal, maxleaf; 1178*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1179*ea844a1aSMatthew Knepley 1180*ea844a1aSMatthew Knepley PetscFunctionBegin; 1181*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1182*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1183*ea844a1aSMatthew Knepley PetscValidLogicalCollectiveBool(s, includeConstraints, 3); 1184*ea844a1aSMatthew Knepley PetscValidLogicalCollectiveBool(s, localOffsets, 4); 1185*ea844a1aSMatthew Knepley PetscValidPointer(gsection, 5); 1186*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), &gs);CHKERRQ(ierr); 1187*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1188*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(gs, pStart, pEnd);CHKERRQ(ierr); 1189*ea844a1aSMatthew Knepley ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1190*ea844a1aSMatthew Knepley nlocal = nroots; /* The local/leaf space matches global/root space */ 1191*ea844a1aSMatthew Knepley /* Must allocate for all points visible to SF, which may be more than this section */ 1192*ea844a1aSMatthew Knepley if (nroots >= 0) { /* nroots < 0 means that the graph has not been set, only happens in serial */ 1193*ea844a1aSMatthew Knepley ierr = PetscSFGetLeafRange(sf, NULL, &maxleaf);CHKERRQ(ierr); 1194*ea844a1aSMatthew Knepley if (nroots < pEnd) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "SF roots %D < pEnd %D", nroots, pEnd); 1195*ea844a1aSMatthew Knepley if (maxleaf >= nroots) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Max local leaf %D >= nroots %D", maxleaf, nroots); 1196*ea844a1aSMatthew Knepley ierr = PetscMalloc2(nroots,&neg,nlocal,&recv);CHKERRQ(ierr); 1197*ea844a1aSMatthew Knepley ierr = PetscArrayzero(neg,nroots);CHKERRQ(ierr); 1198*ea844a1aSMatthew Knepley } 1199*ea844a1aSMatthew Knepley /* Mark all local points with negative dof */ 1200*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1201*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1202*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(gs, p, dof);CHKERRQ(ierr); 1203*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1204*ea844a1aSMatthew Knepley if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(gs, p, cdof);CHKERRQ(ierr);} 1205*ea844a1aSMatthew Knepley if (neg) neg[p] = -(dof+1); 1206*ea844a1aSMatthew Knepley } 1207*ea844a1aSMatthew Knepley ierr = PetscSectionSetUpBC(gs);CHKERRQ(ierr); 1208*ea844a1aSMatthew Knepley if (gs->bcIndices) {ierr = 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]);CHKERRQ(ierr);} 1209*ea844a1aSMatthew Knepley if (nroots >= 0) { 1210*ea844a1aSMatthew Knepley ierr = PetscArrayzero(recv,nlocal);CHKERRQ(ierr); 1211*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, recv);CHKERRQ(ierr); 1212*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, recv);CHKERRQ(ierr); 1213*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1214*ea844a1aSMatthew Knepley if (recv[p] < 0) { 1215*ea844a1aSMatthew Knepley gs->atlasDof[p-pStart] = recv[p]; 1216*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1217*ea844a1aSMatthew Knepley if (-(recv[p]+1) != dof) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Global dof %D for point %D is not the unconstrained %D", -(recv[p]+1), p, dof); 1218*ea844a1aSMatthew Knepley } 1219*ea844a1aSMatthew Knepley } 1220*ea844a1aSMatthew Knepley } 1221*ea844a1aSMatthew Knepley /* Calculate new sizes, get process offset, and calculate point offsets */ 1222*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISGetIndices(s->perm, &pind);CHKERRQ(ierr);} 1223*ea844a1aSMatthew Knepley for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1224*ea844a1aSMatthew Knepley const PetscInt q = pind ? pind[p] : p; 1225*ea844a1aSMatthew Knepley 1226*ea844a1aSMatthew Knepley cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[q] : 0; 1227*ea844a1aSMatthew Knepley gs->atlasOff[q] = off; 1228*ea844a1aSMatthew Knepley off += gs->atlasDof[q] > 0 ? gs->atlasDof[q]-cdof : 0; 1229*ea844a1aSMatthew Knepley } 1230*ea844a1aSMatthew Knepley if (!localOffsets) { 1231*ea844a1aSMatthew Knepley ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 1232*ea844a1aSMatthew Knepley globalOff -= off; 1233*ea844a1aSMatthew Knepley } 1234*ea844a1aSMatthew Knepley for (p = pStart, off = 0; p < pEnd; ++p) { 1235*ea844a1aSMatthew Knepley gs->atlasOff[p-pStart] += globalOff; 1236*ea844a1aSMatthew Knepley if (neg) neg[p] = -(gs->atlasOff[p-pStart]+1); 1237*ea844a1aSMatthew Knepley } 1238*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISRestoreIndices(s->perm, &pind);CHKERRQ(ierr);} 1239*ea844a1aSMatthew Knepley /* Put in negative offsets for ghost points */ 1240*ea844a1aSMatthew Knepley if (nroots >= 0) { 1241*ea844a1aSMatthew Knepley ierr = PetscArrayzero(recv,nlocal);CHKERRQ(ierr); 1242*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, recv);CHKERRQ(ierr); 1243*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, recv);CHKERRQ(ierr); 1244*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1245*ea844a1aSMatthew Knepley if (recv[p] < 0) gs->atlasOff[p-pStart] = recv[p]; 1246*ea844a1aSMatthew Knepley } 1247*ea844a1aSMatthew Knepley } 1248*ea844a1aSMatthew Knepley ierr = PetscFree2(neg,recv);CHKERRQ(ierr); 1249*ea844a1aSMatthew Knepley ierr = PetscSectionViewFromOptions(gs, NULL, "-global_section_view");CHKERRQ(ierr); 1250*ea844a1aSMatthew Knepley *gsection = gs; 1251*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1252*ea844a1aSMatthew Knepley } 1253*ea844a1aSMatthew Knepley 1254*ea844a1aSMatthew Knepley /*@ 1255*ea844a1aSMatthew Knepley PetscSectionCreateGlobalSectionCensored - Create a section describing the global field layout using 1256*ea844a1aSMatthew Knepley the local section and an SF describing the section point overlap. 1257*ea844a1aSMatthew Knepley 1258*ea844a1aSMatthew Knepley Input Parameters: 1259*ea844a1aSMatthew Knepley + s - The PetscSection for the local field layout 1260*ea844a1aSMatthew Knepley . sf - The SF describing parallel layout of the section points 1261*ea844a1aSMatthew Knepley . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1262*ea844a1aSMatthew Knepley . numExcludes - The number of exclusion ranges 1263*ea844a1aSMatthew Knepley - excludes - An array [start_0, end_0, start_1, end_1, ...] where there are numExcludes pairs 1264*ea844a1aSMatthew Knepley 1265*ea844a1aSMatthew Knepley Output Parameter: 1266*ea844a1aSMatthew Knepley . gsection - The PetscSection for the global field layout 1267*ea844a1aSMatthew Knepley 1268*ea844a1aSMatthew Knepley Note: This gives negative sizes and offsets to points not owned by this process 1269*ea844a1aSMatthew Knepley 1270*ea844a1aSMatthew Knepley Level: advanced 1271*ea844a1aSMatthew Knepley 1272*ea844a1aSMatthew Knepley .seealso: PetscSectionCreate() 1273*ea844a1aSMatthew Knepley @*/ 1274*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreateGlobalSectionCensored(PetscSection s, PetscSF sf, PetscBool includeConstraints, PetscInt numExcludes, const PetscInt excludes[], PetscSection *gsection) 1275*ea844a1aSMatthew Knepley { 1276*ea844a1aSMatthew Knepley const PetscInt *pind = NULL; 1277*ea844a1aSMatthew Knepley PetscInt *neg = NULL, *tmpOff = NULL; 1278*ea844a1aSMatthew Knepley PetscInt pStart, pEnd, p, e, dof, cdof, off, globalOff = 0, nroots; 1279*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1280*ea844a1aSMatthew Knepley 1281*ea844a1aSMatthew Knepley PetscFunctionBegin; 1282*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1283*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1284*ea844a1aSMatthew Knepley PetscValidPointer(gsection, 6); 1285*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 1286*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1287*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 1288*ea844a1aSMatthew Knepley ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1289*ea844a1aSMatthew Knepley if (nroots >= 0) { 1290*ea844a1aSMatthew Knepley if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %D < %D section size", nroots, pEnd-pStart); 1291*ea844a1aSMatthew Knepley ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 1292*ea844a1aSMatthew Knepley if (nroots > pEnd-pStart) { 1293*ea844a1aSMatthew Knepley ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 1294*ea844a1aSMatthew Knepley } else { 1295*ea844a1aSMatthew Knepley tmpOff = &(*gsection)->atlasDof[-pStart]; 1296*ea844a1aSMatthew Knepley } 1297*ea844a1aSMatthew Knepley } 1298*ea844a1aSMatthew Knepley /* Mark ghost points with negative dof */ 1299*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1300*ea844a1aSMatthew Knepley for (e = 0; e < numExcludes; ++e) { 1301*ea844a1aSMatthew Knepley if ((p >= excludes[e*2+0]) && (p < excludes[e*2+1])) { 1302*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(*gsection, p, 0);CHKERRQ(ierr); 1303*ea844a1aSMatthew Knepley break; 1304*ea844a1aSMatthew Knepley } 1305*ea844a1aSMatthew Knepley } 1306*ea844a1aSMatthew Knepley if (e < numExcludes) continue; 1307*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1308*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 1309*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1310*ea844a1aSMatthew Knepley if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 1311*ea844a1aSMatthew Knepley if (neg) neg[p] = -(dof+1); 1312*ea844a1aSMatthew Knepley } 1313*ea844a1aSMatthew Knepley ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 1314*ea844a1aSMatthew Knepley if (nroots >= 0) { 1315*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1316*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1317*ea844a1aSMatthew Knepley if (nroots > pEnd - pStart) { 1318*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 1319*ea844a1aSMatthew Knepley } 1320*ea844a1aSMatthew Knepley } 1321*ea844a1aSMatthew Knepley /* Calculate new sizes, get proccess offset, and calculate point offsets */ 1322*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISGetIndices(s->perm, &pind);CHKERRQ(ierr);} 1323*ea844a1aSMatthew Knepley for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1324*ea844a1aSMatthew Knepley const PetscInt q = pind ? pind[p] : p; 1325*ea844a1aSMatthew Knepley 1326*ea844a1aSMatthew Knepley cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[q] : 0; 1327*ea844a1aSMatthew Knepley (*gsection)->atlasOff[q] = off; 1328*ea844a1aSMatthew Knepley off += (*gsection)->atlasDof[q] > 0 ? (*gsection)->atlasDof[q]-cdof : 0; 1329*ea844a1aSMatthew Knepley } 1330*ea844a1aSMatthew Knepley ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 1331*ea844a1aSMatthew Knepley globalOff -= off; 1332*ea844a1aSMatthew Knepley for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1333*ea844a1aSMatthew Knepley (*gsection)->atlasOff[p] += globalOff; 1334*ea844a1aSMatthew Knepley if (neg) neg[p+pStart] = -((*gsection)->atlasOff[p]+1); 1335*ea844a1aSMatthew Knepley } 1336*ea844a1aSMatthew Knepley if (s->perm) {ierr = ISRestoreIndices(s->perm, &pind);CHKERRQ(ierr);} 1337*ea844a1aSMatthew Knepley /* Put in negative offsets for ghost points */ 1338*ea844a1aSMatthew Knepley if (nroots >= 0) { 1339*ea844a1aSMatthew Knepley if (nroots == pEnd-pStart) tmpOff = &(*gsection)->atlasOff[-pStart]; 1340*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1341*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1342*ea844a1aSMatthew Knepley if (nroots > pEnd - pStart) { 1343*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 1344*ea844a1aSMatthew Knepley } 1345*ea844a1aSMatthew Knepley } 1346*ea844a1aSMatthew Knepley if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 1347*ea844a1aSMatthew Knepley ierr = PetscFree(neg);CHKERRQ(ierr); 1348*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1349*ea844a1aSMatthew Knepley } 1350*ea844a1aSMatthew Knepley 1351*ea844a1aSMatthew Knepley /*@ 1352*ea844a1aSMatthew Knepley PetscSectionGetPointLayout - Get the PetscLayout associated with the section points 1353*ea844a1aSMatthew Knepley 1354*ea844a1aSMatthew Knepley Collective on comm 1355*ea844a1aSMatthew Knepley 1356*ea844a1aSMatthew Knepley Input Parameters: 1357*ea844a1aSMatthew Knepley + comm - The MPI_Comm 1358*ea844a1aSMatthew Knepley - s - The PetscSection 1359*ea844a1aSMatthew Knepley 1360*ea844a1aSMatthew Knepley Output Parameter: 1361*ea844a1aSMatthew Knepley . layout - The point layout for the section 1362*ea844a1aSMatthew Knepley 1363*ea844a1aSMatthew Knepley Note: This is usually caleld for the default global section. 1364*ea844a1aSMatthew Knepley 1365*ea844a1aSMatthew Knepley Level: advanced 1366*ea844a1aSMatthew Knepley 1367*ea844a1aSMatthew Knepley .seealso: PetscSectionGetValueLayout(), PetscSectionCreate() 1368*ea844a1aSMatthew Knepley @*/ 1369*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetPointLayout(MPI_Comm comm, PetscSection s, PetscLayout *layout) 1370*ea844a1aSMatthew Knepley { 1371*ea844a1aSMatthew Knepley PetscInt pStart, pEnd, p, localSize = 0; 1372*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1373*ea844a1aSMatthew Knepley 1374*ea844a1aSMatthew Knepley PetscFunctionBegin; 1375*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1376*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1377*ea844a1aSMatthew Knepley PetscInt dof; 1378*ea844a1aSMatthew Knepley 1379*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1380*ea844a1aSMatthew Knepley if (dof > 0) ++localSize; 1381*ea844a1aSMatthew Knepley } 1382*ea844a1aSMatthew Knepley ierr = PetscLayoutCreate(comm, layout);CHKERRQ(ierr); 1383*ea844a1aSMatthew Knepley ierr = PetscLayoutSetLocalSize(*layout, localSize);CHKERRQ(ierr); 1384*ea844a1aSMatthew Knepley ierr = PetscLayoutSetBlockSize(*layout, 1);CHKERRQ(ierr); 1385*ea844a1aSMatthew Knepley ierr = PetscLayoutSetUp(*layout);CHKERRQ(ierr); 1386*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1387*ea844a1aSMatthew Knepley } 1388*ea844a1aSMatthew Knepley 1389*ea844a1aSMatthew Knepley /*@ 1390*ea844a1aSMatthew Knepley PetscSectionGetValueLayout - Get the PetscLayout associated with the section dofs. 1391*ea844a1aSMatthew Knepley 1392*ea844a1aSMatthew Knepley Collective on comm 1393*ea844a1aSMatthew Knepley 1394*ea844a1aSMatthew Knepley Input Parameters: 1395*ea844a1aSMatthew Knepley + comm - The MPI_Comm 1396*ea844a1aSMatthew Knepley - s - The PetscSection 1397*ea844a1aSMatthew Knepley 1398*ea844a1aSMatthew Knepley Output Parameter: 1399*ea844a1aSMatthew Knepley . layout - The dof layout for the section 1400*ea844a1aSMatthew Knepley 1401*ea844a1aSMatthew Knepley Note: This is usually called for the default global section. 1402*ea844a1aSMatthew Knepley 1403*ea844a1aSMatthew Knepley Level: advanced 1404*ea844a1aSMatthew Knepley 1405*ea844a1aSMatthew Knepley .seealso: PetscSectionGetPointLayout(), PetscSectionCreate() 1406*ea844a1aSMatthew Knepley @*/ 1407*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetValueLayout(MPI_Comm comm, PetscSection s, PetscLayout *layout) 1408*ea844a1aSMatthew Knepley { 1409*ea844a1aSMatthew Knepley PetscInt pStart, pEnd, p, localSize = 0; 1410*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1411*ea844a1aSMatthew Knepley 1412*ea844a1aSMatthew Knepley PetscFunctionBegin; 1413*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2); 1414*ea844a1aSMatthew Knepley PetscValidPointer(layout, 3); 1415*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1416*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1417*ea844a1aSMatthew Knepley PetscInt dof,cdof; 1418*ea844a1aSMatthew Knepley 1419*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1420*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1421*ea844a1aSMatthew Knepley if (dof-cdof > 0) localSize += dof-cdof; 1422*ea844a1aSMatthew Knepley } 1423*ea844a1aSMatthew Knepley ierr = PetscLayoutCreate(comm, layout);CHKERRQ(ierr); 1424*ea844a1aSMatthew Knepley ierr = PetscLayoutSetLocalSize(*layout, localSize);CHKERRQ(ierr); 1425*ea844a1aSMatthew Knepley ierr = PetscLayoutSetBlockSize(*layout, 1);CHKERRQ(ierr); 1426*ea844a1aSMatthew Knepley ierr = PetscLayoutSetUp(*layout);CHKERRQ(ierr); 1427*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1428*ea844a1aSMatthew Knepley } 1429*ea844a1aSMatthew Knepley 1430*ea844a1aSMatthew Knepley /*@ 1431*ea844a1aSMatthew Knepley PetscSectionGetOffset - Return the offset into an array or local Vec for the dof associated with the given point. 1432*ea844a1aSMatthew Knepley 1433*ea844a1aSMatthew Knepley Not collective 1434*ea844a1aSMatthew Knepley 1435*ea844a1aSMatthew Knepley Input Parameters: 1436*ea844a1aSMatthew Knepley + s - the PetscSection 1437*ea844a1aSMatthew Knepley - point - the point 1438*ea844a1aSMatthew Knepley 1439*ea844a1aSMatthew Knepley Output Parameter: 1440*ea844a1aSMatthew Knepley . offset - the offset 1441*ea844a1aSMatthew Knepley 1442*ea844a1aSMatthew Knepley Level: intermediate 1443*ea844a1aSMatthew Knepley 1444*ea844a1aSMatthew Knepley .seealso: PetscSectionGetFieldOffset(), PetscSectionCreate() 1445*ea844a1aSMatthew Knepley @*/ 1446*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetOffset(PetscSection s, PetscInt point, PetscInt *offset) 1447*ea844a1aSMatthew Knepley { 1448*ea844a1aSMatthew Knepley PetscFunctionBegin; 1449*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1450*ea844a1aSMatthew Knepley PetscValidPointer(offset, 3); 1451*ea844a1aSMatthew Knepley #if defined(PETSC_USE_DEBUG) 1452*ea844a1aSMatthew Knepley if ((point < s->pStart) || (point >= s->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %D should be in [%D, %D)", point, s->pStart, s->pEnd); 1453*ea844a1aSMatthew Knepley #endif 1454*ea844a1aSMatthew Knepley *offset = s->atlasOff[point - s->pStart]; 1455*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1456*ea844a1aSMatthew Knepley } 1457*ea844a1aSMatthew Knepley 1458*ea844a1aSMatthew Knepley /*@ 1459*ea844a1aSMatthew Knepley PetscSectionSetOffset - Set the offset into an array or local Vec for the dof associated with the given point. 1460*ea844a1aSMatthew Knepley 1461*ea844a1aSMatthew Knepley Not collective 1462*ea844a1aSMatthew Knepley 1463*ea844a1aSMatthew Knepley Input Parameters: 1464*ea844a1aSMatthew Knepley + s - the PetscSection 1465*ea844a1aSMatthew Knepley . point - the point 1466*ea844a1aSMatthew Knepley - offset - the offset 1467*ea844a1aSMatthew Knepley 1468*ea844a1aSMatthew Knepley Note: The user usually does not call this function, but uses PetscSectionSetUp() 1469*ea844a1aSMatthew Knepley 1470*ea844a1aSMatthew Knepley Level: intermediate 1471*ea844a1aSMatthew Knepley 1472*ea844a1aSMatthew Knepley .seealso: PetscSectionGetFieldOffset(), PetscSectionCreate(), PetscSectionSetUp() 1473*ea844a1aSMatthew Knepley @*/ 1474*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetOffset(PetscSection s, PetscInt point, PetscInt offset) 1475*ea844a1aSMatthew Knepley { 1476*ea844a1aSMatthew Knepley PetscFunctionBegin; 1477*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1478*ea844a1aSMatthew Knepley if ((point < s->pStart) || (point >= s->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section point %D should be in [%D, %D)", point, s->pStart, s->pEnd); 1479*ea844a1aSMatthew Knepley s->atlasOff[point - s->pStart] = offset; 1480*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1481*ea844a1aSMatthew Knepley } 1482*ea844a1aSMatthew Knepley 1483*ea844a1aSMatthew Knepley /*@ 1484*ea844a1aSMatthew Knepley PetscSectionGetFieldOffset - Return the offset into an array or local Vec for the dof associated with the given point. 1485*ea844a1aSMatthew Knepley 1486*ea844a1aSMatthew Knepley Not collective 1487*ea844a1aSMatthew Knepley 1488*ea844a1aSMatthew Knepley Input Parameters: 1489*ea844a1aSMatthew Knepley + s - the PetscSection 1490*ea844a1aSMatthew Knepley . point - the point 1491*ea844a1aSMatthew Knepley - field - the field 1492*ea844a1aSMatthew Knepley 1493*ea844a1aSMatthew Knepley Output Parameter: 1494*ea844a1aSMatthew Knepley . offset - the offset 1495*ea844a1aSMatthew Knepley 1496*ea844a1aSMatthew Knepley Level: intermediate 1497*ea844a1aSMatthew Knepley 1498*ea844a1aSMatthew Knepley .seealso: PetscSectionGetOffset(), PetscSectionCreate() 1499*ea844a1aSMatthew Knepley @*/ 1500*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt *offset) 1501*ea844a1aSMatthew Knepley { 1502*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1503*ea844a1aSMatthew Knepley 1504*ea844a1aSMatthew Knepley PetscFunctionBegin; 1505*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1506*ea844a1aSMatthew Knepley PetscValidPointer(offset, 4); 1507*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 1508*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s->field[field], point, offset);CHKERRQ(ierr); 1509*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1510*ea844a1aSMatthew Knepley } 1511*ea844a1aSMatthew Knepley 1512*ea844a1aSMatthew Knepley /*@ 1513*ea844a1aSMatthew Knepley PetscSectionSetFieldOffset - Set the offset into an array or local Vec for the dof associated with the given point. 1514*ea844a1aSMatthew Knepley 1515*ea844a1aSMatthew Knepley Not collective 1516*ea844a1aSMatthew Knepley 1517*ea844a1aSMatthew Knepley Input Parameters: 1518*ea844a1aSMatthew Knepley + s - the PetscSection 1519*ea844a1aSMatthew Knepley . point - the point 1520*ea844a1aSMatthew Knepley . field - the field 1521*ea844a1aSMatthew Knepley - offset - the offset 1522*ea844a1aSMatthew Knepley 1523*ea844a1aSMatthew Knepley Note: The user usually does not call this function, but uses PetscSectionSetUp() 1524*ea844a1aSMatthew Knepley 1525*ea844a1aSMatthew Knepley Level: intermediate 1526*ea844a1aSMatthew Knepley 1527*ea844a1aSMatthew Knepley .seealso: PetscSectionGetOffset(), PetscSectionCreate(), PetscSectionSetUp() 1528*ea844a1aSMatthew Knepley @*/ 1529*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt offset) 1530*ea844a1aSMatthew Knepley { 1531*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1532*ea844a1aSMatthew Knepley 1533*ea844a1aSMatthew Knepley PetscFunctionBegin; 1534*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1535*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 1536*ea844a1aSMatthew Knepley ierr = PetscSectionSetOffset(s->field[field], point, offset);CHKERRQ(ierr); 1537*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1538*ea844a1aSMatthew Knepley } 1539*ea844a1aSMatthew Knepley 1540*ea844a1aSMatthew Knepley /*@ 1541*ea844a1aSMatthew Knepley PetscSectionGetFieldPointOffset - Return the offset on the given point for the dof associated with the given point. 1542*ea844a1aSMatthew Knepley 1543*ea844a1aSMatthew Knepley Not collective 1544*ea844a1aSMatthew Knepley 1545*ea844a1aSMatthew Knepley Input Parameters: 1546*ea844a1aSMatthew Knepley + s - the PetscSection 1547*ea844a1aSMatthew Knepley . point - the point 1548*ea844a1aSMatthew Knepley - field - the field 1549*ea844a1aSMatthew Knepley 1550*ea844a1aSMatthew Knepley Output Parameter: 1551*ea844a1aSMatthew Knepley . offset - the offset 1552*ea844a1aSMatthew Knepley 1553*ea844a1aSMatthew Knepley Note: This gives the offset on a point of the field, ignoring constraints, meaning starting at the first dof for 1554*ea844a1aSMatthew Knepley this point, what number is the first dof with this field. 1555*ea844a1aSMatthew Knepley 1556*ea844a1aSMatthew Knepley Level: advanced 1557*ea844a1aSMatthew Knepley 1558*ea844a1aSMatthew Knepley .seealso: PetscSectionGetOffset(), PetscSectionCreate() 1559*ea844a1aSMatthew Knepley @*/ 1560*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldPointOffset(PetscSection s, PetscInt point, PetscInt field, PetscInt *offset) 1561*ea844a1aSMatthew Knepley { 1562*ea844a1aSMatthew Knepley PetscInt off, foff; 1563*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1564*ea844a1aSMatthew Knepley 1565*ea844a1aSMatthew Knepley PetscFunctionBegin; 1566*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1567*ea844a1aSMatthew Knepley PetscValidPointer(offset, 4); 1568*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 1569*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s, point, &off);CHKERRQ(ierr); 1570*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s->field[field], point, &foff);CHKERRQ(ierr); 1571*ea844a1aSMatthew Knepley *offset = foff - off; 1572*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1573*ea844a1aSMatthew Knepley } 1574*ea844a1aSMatthew Knepley 1575*ea844a1aSMatthew Knepley /*@ 1576*ea844a1aSMatthew Knepley PetscSectionGetOffsetRange - Return the full range of offsets [start, end) 1577*ea844a1aSMatthew Knepley 1578*ea844a1aSMatthew Knepley Not collective 1579*ea844a1aSMatthew Knepley 1580*ea844a1aSMatthew Knepley Input Parameter: 1581*ea844a1aSMatthew Knepley . s - the PetscSection 1582*ea844a1aSMatthew Knepley 1583*ea844a1aSMatthew Knepley Output Parameters: 1584*ea844a1aSMatthew Knepley + start - the minimum offset 1585*ea844a1aSMatthew Knepley - end - one more than the maximum offset 1586*ea844a1aSMatthew Knepley 1587*ea844a1aSMatthew Knepley Level: intermediate 1588*ea844a1aSMatthew Knepley 1589*ea844a1aSMatthew Knepley .seealso: PetscSectionGetOffset(), PetscSectionCreate() 1590*ea844a1aSMatthew Knepley @*/ 1591*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetOffsetRange(PetscSection s, PetscInt *start, PetscInt *end) 1592*ea844a1aSMatthew Knepley { 1593*ea844a1aSMatthew Knepley PetscInt os = 0, oe = 0, pStart, pEnd, p; 1594*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1595*ea844a1aSMatthew Knepley 1596*ea844a1aSMatthew Knepley PetscFunctionBegin; 1597*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1598*ea844a1aSMatthew Knepley if (s->atlasOff) {os = s->atlasOff[0]; oe = s->atlasOff[0];} 1599*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1600*ea844a1aSMatthew Knepley for (p = 0; p < pEnd-pStart; ++p) { 1601*ea844a1aSMatthew Knepley PetscInt dof = s->atlasDof[p], off = s->atlasOff[p]; 1602*ea844a1aSMatthew Knepley 1603*ea844a1aSMatthew Knepley if (off >= 0) { 1604*ea844a1aSMatthew Knepley os = PetscMin(os, off); 1605*ea844a1aSMatthew Knepley oe = PetscMax(oe, off+dof); 1606*ea844a1aSMatthew Knepley } 1607*ea844a1aSMatthew Knepley } 1608*ea844a1aSMatthew Knepley if (start) *start = os; 1609*ea844a1aSMatthew Knepley if (end) *end = oe; 1610*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1611*ea844a1aSMatthew Knepley } 1612*ea844a1aSMatthew Knepley 1613*ea844a1aSMatthew Knepley /*@ 1614*ea844a1aSMatthew Knepley PetscSectionCreateSubsection - Create a new, smaller section composed of only the selected fields 1615*ea844a1aSMatthew Knepley 1616*ea844a1aSMatthew Knepley Collective on s 1617*ea844a1aSMatthew Knepley 1618*ea844a1aSMatthew Knepley Input Parameter: 1619*ea844a1aSMatthew Knepley + s - the PetscSection 1620*ea844a1aSMatthew Knepley . len - the number of subfields 1621*ea844a1aSMatthew Knepley - fields - the subfield numbers 1622*ea844a1aSMatthew Knepley 1623*ea844a1aSMatthew Knepley Output Parameter: 1624*ea844a1aSMatthew Knepley . subs - the subsection 1625*ea844a1aSMatthew Knepley 1626*ea844a1aSMatthew Knepley Note: The section offsets now refer to a new, smaller vector. 1627*ea844a1aSMatthew Knepley 1628*ea844a1aSMatthew Knepley Level: advanced 1629*ea844a1aSMatthew Knepley 1630*ea844a1aSMatthew Knepley .seealso: PetscSectionCreateSupersection(), PetscSectionCreate() 1631*ea844a1aSMatthew Knepley @*/ 1632*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreateSubsection(PetscSection s, PetscInt len, const PetscInt fields[], PetscSection *subs) 1633*ea844a1aSMatthew Knepley { 1634*ea844a1aSMatthew Knepley PetscInt nF, f, pStart, pEnd, p, maxCdof = 0; 1635*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1636*ea844a1aSMatthew Knepley 1637*ea844a1aSMatthew Knepley PetscFunctionBegin; 1638*ea844a1aSMatthew Knepley if (!len) PetscFunctionReturn(0); 1639*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1640*ea844a1aSMatthew Knepley PetscValidPointer(fields, 3); 1641*ea844a1aSMatthew Knepley PetscValidPointer(subs, 4); 1642*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s, &nF);CHKERRQ(ierr); 1643*ea844a1aSMatthew Knepley if (len > nF) SETERRQ2(PetscObjectComm((PetscObject) s), PETSC_ERR_ARG_WRONG, "Number of requested fields %D greater than number of fields %D", len, nF); 1644*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), subs);CHKERRQ(ierr); 1645*ea844a1aSMatthew Knepley ierr = PetscSectionSetNumFields(*subs, len);CHKERRQ(ierr); 1646*ea844a1aSMatthew Knepley for (f = 0; f < len; ++f) { 1647*ea844a1aSMatthew Knepley const char *name = NULL; 1648*ea844a1aSMatthew Knepley PetscInt numComp = 0; 1649*ea844a1aSMatthew Knepley 1650*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldName(s, fields[f], &name);CHKERRQ(ierr); 1651*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldName(*subs, f, name);CHKERRQ(ierr); 1652*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s, fields[f], &numComp);CHKERRQ(ierr); 1653*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(*subs, f, numComp);CHKERRQ(ierr); 1654*ea844a1aSMatthew Knepley } 1655*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1656*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(*subs, pStart, pEnd);CHKERRQ(ierr); 1657*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1658*ea844a1aSMatthew Knepley PetscInt dof = 0, cdof = 0, fdof = 0, cfdof = 0; 1659*ea844a1aSMatthew Knepley 1660*ea844a1aSMatthew Knepley for (f = 0; f < len; ++f) { 1661*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s, p, fields[f], &fdof);CHKERRQ(ierr); 1662*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldDof(*subs, p, f, fdof);CHKERRQ(ierr); 1663*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s, p, fields[f], &cfdof);CHKERRQ(ierr); 1664*ea844a1aSMatthew Knepley if (cfdof) {ierr = PetscSectionSetFieldConstraintDof(*subs, p, f, cfdof);CHKERRQ(ierr);} 1665*ea844a1aSMatthew Knepley dof += fdof; 1666*ea844a1aSMatthew Knepley cdof += cfdof; 1667*ea844a1aSMatthew Knepley } 1668*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(*subs, p, dof);CHKERRQ(ierr); 1669*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetConstraintDof(*subs, p, cdof);CHKERRQ(ierr);} 1670*ea844a1aSMatthew Knepley maxCdof = PetscMax(cdof, maxCdof); 1671*ea844a1aSMatthew Knepley } 1672*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(*subs);CHKERRQ(ierr); 1673*ea844a1aSMatthew Knepley if (maxCdof) { 1674*ea844a1aSMatthew Knepley PetscInt *indices; 1675*ea844a1aSMatthew Knepley 1676*ea844a1aSMatthew Knepley ierr = PetscMalloc1(maxCdof, &indices);CHKERRQ(ierr); 1677*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1678*ea844a1aSMatthew Knepley PetscInt cdof; 1679*ea844a1aSMatthew Knepley 1680*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(*subs, p, &cdof);CHKERRQ(ierr); 1681*ea844a1aSMatthew Knepley if (cdof) { 1682*ea844a1aSMatthew Knepley const PetscInt *oldIndices = NULL; 1683*ea844a1aSMatthew Knepley PetscInt fdof = 0, cfdof = 0, fc, numConst = 0, fOff = 0; 1684*ea844a1aSMatthew Knepley 1685*ea844a1aSMatthew Knepley for (f = 0; f < len; ++f) { 1686*ea844a1aSMatthew Knepley PetscInt oldFoff = 0, oldf; 1687*ea844a1aSMatthew Knepley 1688*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s, p, fields[f], &fdof);CHKERRQ(ierr); 1689*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s, p, fields[f], &cfdof);CHKERRQ(ierr); 1690*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s, p, fields[f], &oldIndices);CHKERRQ(ierr); 1691*ea844a1aSMatthew Knepley /* This can be sped up if we assume sorted fields */ 1692*ea844a1aSMatthew Knepley for (oldf = 0; oldf < fields[f]; ++oldf) { 1693*ea844a1aSMatthew Knepley PetscInt oldfdof = 0; 1694*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s, p, oldf, &oldfdof);CHKERRQ(ierr); 1695*ea844a1aSMatthew Knepley oldFoff += oldfdof; 1696*ea844a1aSMatthew Knepley } 1697*ea844a1aSMatthew Knepley for (fc = 0; fc < cfdof; ++fc) indices[numConst+fc] = oldIndices[fc] + (fOff - oldFoff); 1698*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldConstraintIndices(*subs, p, f, &indices[numConst]);CHKERRQ(ierr); 1699*ea844a1aSMatthew Knepley numConst += cfdof; 1700*ea844a1aSMatthew Knepley fOff += fdof; 1701*ea844a1aSMatthew Knepley } 1702*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(*subs, p, indices);CHKERRQ(ierr); 1703*ea844a1aSMatthew Knepley } 1704*ea844a1aSMatthew Knepley } 1705*ea844a1aSMatthew Knepley ierr = PetscFree(indices);CHKERRQ(ierr); 1706*ea844a1aSMatthew Knepley } 1707*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1708*ea844a1aSMatthew Knepley } 1709*ea844a1aSMatthew Knepley 1710*ea844a1aSMatthew Knepley /*@ 1711*ea844a1aSMatthew Knepley PetscSectionCreateSupersection - Create a new, larger section composed of the input sections 1712*ea844a1aSMatthew Knepley 1713*ea844a1aSMatthew Knepley Collective on s 1714*ea844a1aSMatthew Knepley 1715*ea844a1aSMatthew Knepley Input Parameters: 1716*ea844a1aSMatthew Knepley + s - the input sections 1717*ea844a1aSMatthew Knepley - len - the number of input sections 1718*ea844a1aSMatthew Knepley 1719*ea844a1aSMatthew Knepley Output Parameter: 1720*ea844a1aSMatthew Knepley . supers - the supersection 1721*ea844a1aSMatthew Knepley 1722*ea844a1aSMatthew Knepley Note: The section offsets now refer to a new, larger vector. 1723*ea844a1aSMatthew Knepley 1724*ea844a1aSMatthew Knepley Level: advanced 1725*ea844a1aSMatthew Knepley 1726*ea844a1aSMatthew Knepley .seealso: PetscSectionCreateSubsection(), PetscSectionCreate() 1727*ea844a1aSMatthew Knepley @*/ 1728*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreateSupersection(PetscSection s[], PetscInt len, PetscSection *supers) 1729*ea844a1aSMatthew Knepley { 1730*ea844a1aSMatthew Knepley PetscInt Nf = 0, f, pStart = PETSC_MAX_INT, pEnd = 0, p, maxCdof = 0, i; 1731*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1732*ea844a1aSMatthew Knepley 1733*ea844a1aSMatthew Knepley PetscFunctionBegin; 1734*ea844a1aSMatthew Knepley if (!len) PetscFunctionReturn(0); 1735*ea844a1aSMatthew Knepley for (i = 0; i < len; ++i) { 1736*ea844a1aSMatthew Knepley PetscInt nf, pStarti, pEndi; 1737*ea844a1aSMatthew Knepley 1738*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s[i], &nf);CHKERRQ(ierr); 1739*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s[i], &pStarti, &pEndi);CHKERRQ(ierr); 1740*ea844a1aSMatthew Knepley pStart = PetscMin(pStart, pStarti); 1741*ea844a1aSMatthew Knepley pEnd = PetscMax(pEnd, pEndi); 1742*ea844a1aSMatthew Knepley Nf += nf; 1743*ea844a1aSMatthew Knepley } 1744*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s[0]), supers);CHKERRQ(ierr); 1745*ea844a1aSMatthew Knepley ierr = PetscSectionSetNumFields(*supers, Nf);CHKERRQ(ierr); 1746*ea844a1aSMatthew Knepley for (i = 0, f = 0; i < len; ++i) { 1747*ea844a1aSMatthew Knepley PetscInt nf, fi; 1748*ea844a1aSMatthew Knepley 1749*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s[i], &nf);CHKERRQ(ierr); 1750*ea844a1aSMatthew Knepley for (fi = 0; fi < nf; ++fi, ++f) { 1751*ea844a1aSMatthew Knepley const char *name = NULL; 1752*ea844a1aSMatthew Knepley PetscInt numComp = 0; 1753*ea844a1aSMatthew Knepley 1754*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldName(s[i], fi, &name);CHKERRQ(ierr); 1755*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldName(*supers, f, name);CHKERRQ(ierr); 1756*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s[i], fi, &numComp);CHKERRQ(ierr); 1757*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(*supers, f, numComp);CHKERRQ(ierr); 1758*ea844a1aSMatthew Knepley } 1759*ea844a1aSMatthew Knepley } 1760*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(*supers, pStart, pEnd);CHKERRQ(ierr); 1761*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1762*ea844a1aSMatthew Knepley PetscInt dof = 0, cdof = 0; 1763*ea844a1aSMatthew Knepley 1764*ea844a1aSMatthew Knepley for (i = 0, f = 0; i < len; ++i) { 1765*ea844a1aSMatthew Knepley PetscInt nf, fi, pStarti, pEndi; 1766*ea844a1aSMatthew Knepley PetscInt fdof = 0, cfdof = 0; 1767*ea844a1aSMatthew Knepley 1768*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s[i], &nf);CHKERRQ(ierr); 1769*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s[i], &pStarti, &pEndi);CHKERRQ(ierr); 1770*ea844a1aSMatthew Knepley if ((p < pStarti) || (p >= pEndi)) continue; 1771*ea844a1aSMatthew Knepley for (fi = 0; fi < nf; ++fi, ++f) { 1772*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s[i], p, fi, &fdof);CHKERRQ(ierr); 1773*ea844a1aSMatthew Knepley ierr = PetscSectionAddFieldDof(*supers, p, f, fdof);CHKERRQ(ierr); 1774*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s[i], p, fi, &cfdof);CHKERRQ(ierr); 1775*ea844a1aSMatthew Knepley if (cfdof) {ierr = PetscSectionAddFieldConstraintDof(*supers, p, f, cfdof);CHKERRQ(ierr);} 1776*ea844a1aSMatthew Knepley dof += fdof; 1777*ea844a1aSMatthew Knepley cdof += cfdof; 1778*ea844a1aSMatthew Knepley } 1779*ea844a1aSMatthew Knepley } 1780*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(*supers, p, dof);CHKERRQ(ierr); 1781*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetConstraintDof(*supers, p, cdof);CHKERRQ(ierr);} 1782*ea844a1aSMatthew Knepley maxCdof = PetscMax(cdof, maxCdof); 1783*ea844a1aSMatthew Knepley } 1784*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(*supers);CHKERRQ(ierr); 1785*ea844a1aSMatthew Knepley if (maxCdof) { 1786*ea844a1aSMatthew Knepley PetscInt *indices; 1787*ea844a1aSMatthew Knepley 1788*ea844a1aSMatthew Knepley ierr = PetscMalloc1(maxCdof, &indices);CHKERRQ(ierr); 1789*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1790*ea844a1aSMatthew Knepley PetscInt cdof; 1791*ea844a1aSMatthew Knepley 1792*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(*supers, p, &cdof);CHKERRQ(ierr); 1793*ea844a1aSMatthew Knepley if (cdof) { 1794*ea844a1aSMatthew Knepley PetscInt dof, numConst = 0, fOff = 0; 1795*ea844a1aSMatthew Knepley 1796*ea844a1aSMatthew Knepley for (i = 0, f = 0; i < len; ++i) { 1797*ea844a1aSMatthew Knepley const PetscInt *oldIndices = NULL; 1798*ea844a1aSMatthew Knepley PetscInt nf, fi, pStarti, pEndi, fdof, cfdof, fc; 1799*ea844a1aSMatthew Knepley 1800*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s[i], &nf);CHKERRQ(ierr); 1801*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s[i], &pStarti, &pEndi);CHKERRQ(ierr); 1802*ea844a1aSMatthew Knepley if ((p < pStarti) || (p >= pEndi)) continue; 1803*ea844a1aSMatthew Knepley for (fi = 0; fi < nf; ++fi, ++f) { 1804*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s[i], p, fi, &fdof);CHKERRQ(ierr); 1805*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s[i], p, fi, &cfdof);CHKERRQ(ierr); 1806*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s[i], p, fi, &oldIndices);CHKERRQ(ierr); 1807*ea844a1aSMatthew Knepley for (fc = 0; fc < cfdof; ++fc) indices[numConst+fc] = oldIndices[fc] + fOff; 1808*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldConstraintIndices(*supers, p, f, &indices[numConst]);CHKERRQ(ierr); 1809*ea844a1aSMatthew Knepley numConst += cfdof; 1810*ea844a1aSMatthew Knepley } 1811*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s[i], p, &dof);CHKERRQ(ierr); 1812*ea844a1aSMatthew Knepley fOff += dof; 1813*ea844a1aSMatthew Knepley } 1814*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(*supers, p, indices);CHKERRQ(ierr); 1815*ea844a1aSMatthew Knepley } 1816*ea844a1aSMatthew Knepley } 1817*ea844a1aSMatthew Knepley ierr = PetscFree(indices);CHKERRQ(ierr); 1818*ea844a1aSMatthew Knepley } 1819*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1820*ea844a1aSMatthew Knepley } 1821*ea844a1aSMatthew Knepley 1822*ea844a1aSMatthew Knepley /*@ 1823*ea844a1aSMatthew Knepley PetscSectionCreateSubmeshSection - Create a new, smaller section with support on the submesh 1824*ea844a1aSMatthew Knepley 1825*ea844a1aSMatthew Knepley Collective on s 1826*ea844a1aSMatthew Knepley 1827*ea844a1aSMatthew Knepley Input Parameters: 1828*ea844a1aSMatthew Knepley + s - the PetscSection 1829*ea844a1aSMatthew Knepley - subpointMap - a sorted list of points in the original mesh which are in the submesh 1830*ea844a1aSMatthew Knepley 1831*ea844a1aSMatthew Knepley Output Parameter: 1832*ea844a1aSMatthew Knepley . subs - the subsection 1833*ea844a1aSMatthew Knepley 1834*ea844a1aSMatthew Knepley Note: The section offsets now refer to a new, smaller vector. 1835*ea844a1aSMatthew Knepley 1836*ea844a1aSMatthew Knepley Level: advanced 1837*ea844a1aSMatthew Knepley 1838*ea844a1aSMatthew Knepley .seealso: PetscSectionCreateSubsection(), DMPlexGetSubpointMap(), PetscSectionCreate() 1839*ea844a1aSMatthew Knepley @*/ 1840*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionCreateSubmeshSection(PetscSection s, IS subpointMap, PetscSection *subs) 1841*ea844a1aSMatthew Knepley { 1842*ea844a1aSMatthew Knepley const PetscInt *points = NULL, *indices = NULL; 1843*ea844a1aSMatthew Knepley PetscInt numFields, f, numSubpoints = 0, pStart, pEnd, p, subp; 1844*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1845*ea844a1aSMatthew Knepley 1846*ea844a1aSMatthew Knepley PetscFunctionBegin; 1847*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1848*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(subpointMap, IS_CLASSID, 2); 1849*ea844a1aSMatthew Knepley PetscValidPointer(subs, 3); 1850*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s, &numFields);CHKERRQ(ierr); 1851*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), subs);CHKERRQ(ierr); 1852*ea844a1aSMatthew Knepley if (numFields) {ierr = PetscSectionSetNumFields(*subs, numFields);CHKERRQ(ierr);} 1853*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 1854*ea844a1aSMatthew Knepley const char *name = NULL; 1855*ea844a1aSMatthew Knepley PetscInt numComp = 0; 1856*ea844a1aSMatthew Knepley 1857*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldName(s, f, &name);CHKERRQ(ierr); 1858*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldName(*subs, f, name);CHKERRQ(ierr); 1859*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s, f, &numComp);CHKERRQ(ierr); 1860*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(*subs, f, numComp);CHKERRQ(ierr); 1861*ea844a1aSMatthew Knepley } 1862*ea844a1aSMatthew Knepley /* For right now, we do not try to squeeze the subchart */ 1863*ea844a1aSMatthew Knepley if (subpointMap) { 1864*ea844a1aSMatthew Knepley ierr = ISGetSize(subpointMap, &numSubpoints);CHKERRQ(ierr); 1865*ea844a1aSMatthew Knepley ierr = ISGetIndices(subpointMap, &points);CHKERRQ(ierr); 1866*ea844a1aSMatthew Knepley } 1867*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1868*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(*subs, 0, numSubpoints);CHKERRQ(ierr); 1869*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1870*ea844a1aSMatthew Knepley PetscInt dof, cdof, fdof = 0, cfdof = 0; 1871*ea844a1aSMatthew Knepley 1872*ea844a1aSMatthew Knepley ierr = PetscFindInt(p, numSubpoints, points, &subp);CHKERRQ(ierr); 1873*ea844a1aSMatthew Knepley if (subp < 0) continue; 1874*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 1875*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s, p, f, &fdof);CHKERRQ(ierr); 1876*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldDof(*subs, subp, f, fdof);CHKERRQ(ierr); 1877*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s, p, f, &cfdof);CHKERRQ(ierr); 1878*ea844a1aSMatthew Knepley if (cfdof) {ierr = PetscSectionSetFieldConstraintDof(*subs, subp, f, cfdof);CHKERRQ(ierr);} 1879*ea844a1aSMatthew Knepley } 1880*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1881*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(*subs, subp, dof);CHKERRQ(ierr); 1882*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1883*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetConstraintDof(*subs, subp, cdof);CHKERRQ(ierr);} 1884*ea844a1aSMatthew Knepley } 1885*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(*subs);CHKERRQ(ierr); 1886*ea844a1aSMatthew Knepley /* Change offsets to original offsets */ 1887*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 1888*ea844a1aSMatthew Knepley PetscInt off, foff = 0; 1889*ea844a1aSMatthew Knepley 1890*ea844a1aSMatthew Knepley ierr = PetscFindInt(p, numSubpoints, points, &subp);CHKERRQ(ierr); 1891*ea844a1aSMatthew Knepley if (subp < 0) continue; 1892*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 1893*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldOffset(s, p, f, &foff);CHKERRQ(ierr); 1894*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldOffset(*subs, subp, f, foff);CHKERRQ(ierr); 1895*ea844a1aSMatthew Knepley } 1896*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 1897*ea844a1aSMatthew Knepley ierr = PetscSectionSetOffset(*subs, subp, off);CHKERRQ(ierr); 1898*ea844a1aSMatthew Knepley } 1899*ea844a1aSMatthew Knepley /* Copy constraint indices */ 1900*ea844a1aSMatthew Knepley for (subp = 0; subp < numSubpoints; ++subp) { 1901*ea844a1aSMatthew Knepley PetscInt cdof; 1902*ea844a1aSMatthew Knepley 1903*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(*subs, subp, &cdof);CHKERRQ(ierr); 1904*ea844a1aSMatthew Knepley if (cdof) { 1905*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 1906*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s, points[subp], f, &indices);CHKERRQ(ierr); 1907*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldConstraintIndices(*subs, subp, f, indices);CHKERRQ(ierr); 1908*ea844a1aSMatthew Knepley } 1909*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s, points[subp], &indices);CHKERRQ(ierr); 1910*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(*subs, subp, indices);CHKERRQ(ierr); 1911*ea844a1aSMatthew Knepley } 1912*ea844a1aSMatthew Knepley } 1913*ea844a1aSMatthew Knepley if (subpointMap) {ierr = ISRestoreIndices(subpointMap, &points);CHKERRQ(ierr);} 1914*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1915*ea844a1aSMatthew Knepley } 1916*ea844a1aSMatthew Knepley 1917*ea844a1aSMatthew Knepley static PetscErrorCode PetscSectionView_ASCII(PetscSection s, PetscViewer viewer) 1918*ea844a1aSMatthew Knepley { 1919*ea844a1aSMatthew Knepley PetscInt p; 1920*ea844a1aSMatthew Knepley PetscMPIInt rank; 1921*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1922*ea844a1aSMatthew Knepley 1923*ea844a1aSMatthew Knepley PetscFunctionBegin; 1924*ea844a1aSMatthew Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRQ(ierr); 1925*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 1926*ea844a1aSMatthew Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "Process %d:\n", rank);CHKERRQ(ierr); 1927*ea844a1aSMatthew Knepley for (p = 0; p < s->pEnd - s->pStart; ++p) { 1928*ea844a1aSMatthew Knepley if ((s->bc) && (s->bc->atlasDof[p] > 0)) { 1929*ea844a1aSMatthew Knepley PetscInt b; 1930*ea844a1aSMatthew Knepley 1931*ea844a1aSMatthew Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " (%4D) dim %2D offset %3D constrained", p+s->pStart, s->atlasDof[p], s->atlasOff[p]);CHKERRQ(ierr); 1932*ea844a1aSMatthew Knepley for (b = 0; b < s->bc->atlasDof[p]; ++b) { 1933*ea844a1aSMatthew Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " %D", s->bcIndices[s->bc->atlasOff[p]+b]);CHKERRQ(ierr); 1934*ea844a1aSMatthew Knepley } 1935*ea844a1aSMatthew Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\n");CHKERRQ(ierr); 1936*ea844a1aSMatthew Knepley } else { 1937*ea844a1aSMatthew Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " (%4D) dim %2D offset %3D\n", p+s->pStart, s->atlasDof[p], s->atlasOff[p]);CHKERRQ(ierr); 1938*ea844a1aSMatthew Knepley } 1939*ea844a1aSMatthew Knepley } 1940*ea844a1aSMatthew Knepley ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1941*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 1942*ea844a1aSMatthew Knepley if (s->sym) { 1943*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1944*ea844a1aSMatthew Knepley ierr = PetscSectionSymView(s->sym,viewer);CHKERRQ(ierr); 1945*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1946*ea844a1aSMatthew Knepley } 1947*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1948*ea844a1aSMatthew Knepley } 1949*ea844a1aSMatthew Knepley 1950*ea844a1aSMatthew Knepley /*@C 1951*ea844a1aSMatthew Knepley PetscSectionView - Views a PetscSection 1952*ea844a1aSMatthew Knepley 1953*ea844a1aSMatthew Knepley Collective on PetscSection 1954*ea844a1aSMatthew Knepley 1955*ea844a1aSMatthew Knepley Input Parameters: 1956*ea844a1aSMatthew Knepley + s - the PetscSection object to view 1957*ea844a1aSMatthew Knepley - v - the viewer 1958*ea844a1aSMatthew Knepley 1959*ea844a1aSMatthew Knepley Level: beginner 1960*ea844a1aSMatthew Knepley 1961*ea844a1aSMatthew Knepley .seealso PetscSectionCreate(), PetscSectionDestroy() 1962*ea844a1aSMatthew Knepley @*/ 1963*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionView(PetscSection s, PetscViewer viewer) 1964*ea844a1aSMatthew Knepley { 1965*ea844a1aSMatthew Knepley PetscBool isascii; 1966*ea844a1aSMatthew Knepley PetscInt f; 1967*ea844a1aSMatthew Knepley PetscErrorCode ierr; 1968*ea844a1aSMatthew Knepley 1969*ea844a1aSMatthew Knepley PetscFunctionBegin; 1970*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1971*ea844a1aSMatthew Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)s), &viewer);CHKERRQ(ierr);} 1972*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1973*ea844a1aSMatthew Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 1974*ea844a1aSMatthew Knepley if (isascii) { 1975*ea844a1aSMatthew Knepley ierr = PetscObjectPrintClassNamePrefixType((PetscObject)s,viewer);CHKERRQ(ierr); 1976*ea844a1aSMatthew Knepley if (s->numFields) { 1977*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D fields\n", s->numFields);CHKERRQ(ierr); 1978*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) { 1979*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer, " field %D with %D components\n", f, s->numFieldComponents[f]);CHKERRQ(ierr); 1980*ea844a1aSMatthew Knepley ierr = PetscSectionView_ASCII(s->field[f], viewer);CHKERRQ(ierr); 1981*ea844a1aSMatthew Knepley } 1982*ea844a1aSMatthew Knepley } else { 1983*ea844a1aSMatthew Knepley ierr = PetscSectionView_ASCII(s, viewer);CHKERRQ(ierr); 1984*ea844a1aSMatthew Knepley } 1985*ea844a1aSMatthew Knepley } 1986*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 1987*ea844a1aSMatthew Knepley } 1988*ea844a1aSMatthew Knepley 1989*ea844a1aSMatthew Knepley /*@ 1990*ea844a1aSMatthew Knepley PetscSectionReset - Frees all section data. 1991*ea844a1aSMatthew Knepley 1992*ea844a1aSMatthew Knepley Not collective 1993*ea844a1aSMatthew Knepley 1994*ea844a1aSMatthew Knepley Input Parameters: 1995*ea844a1aSMatthew Knepley . s - the PetscSection 1996*ea844a1aSMatthew Knepley 1997*ea844a1aSMatthew Knepley Level: beginner 1998*ea844a1aSMatthew Knepley 1999*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate() 2000*ea844a1aSMatthew Knepley @*/ 2001*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionReset(PetscSection s) 2002*ea844a1aSMatthew Knepley { 2003*ea844a1aSMatthew Knepley PetscInt f; 2004*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2005*ea844a1aSMatthew Knepley 2006*ea844a1aSMatthew Knepley PetscFunctionBegin; 2007*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2008*ea844a1aSMatthew Knepley ierr = PetscFree(s->numFieldComponents);CHKERRQ(ierr); 2009*ea844a1aSMatthew Knepley for (f = 0; f < s->numFields; ++f) { 2010*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(&s->field[f]);CHKERRQ(ierr); 2011*ea844a1aSMatthew Knepley ierr = PetscFree(s->fieldNames[f]);CHKERRQ(ierr); 2012*ea844a1aSMatthew Knepley } 2013*ea844a1aSMatthew Knepley ierr = PetscFree(s->fieldNames);CHKERRQ(ierr); 2014*ea844a1aSMatthew Knepley ierr = PetscFree(s->field);CHKERRQ(ierr); 2015*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(&s->bc);CHKERRQ(ierr); 2016*ea844a1aSMatthew Knepley ierr = PetscFree(s->bcIndices);CHKERRQ(ierr); 2017*ea844a1aSMatthew Knepley ierr = PetscFree2(s->atlasDof, s->atlasOff);CHKERRQ(ierr); 2018*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(&s->clSection);CHKERRQ(ierr); 2019*ea844a1aSMatthew Knepley ierr = ISDestroy(&s->clPoints);CHKERRQ(ierr); 2020*ea844a1aSMatthew Knepley ierr = ISDestroy(&s->perm);CHKERRQ(ierr); 2021*ea844a1aSMatthew Knepley ierr = PetscFree(s->clPerm);CHKERRQ(ierr); 2022*ea844a1aSMatthew Knepley ierr = PetscFree(s->clInvPerm);CHKERRQ(ierr); 2023*ea844a1aSMatthew Knepley ierr = PetscSectionSymDestroy(&s->sym);CHKERRQ(ierr); 2024*ea844a1aSMatthew Knepley 2025*ea844a1aSMatthew Knepley s->pStart = -1; 2026*ea844a1aSMatthew Knepley s->pEnd = -1; 2027*ea844a1aSMatthew Knepley s->maxDof = 0; 2028*ea844a1aSMatthew Knepley s->setup = PETSC_FALSE; 2029*ea844a1aSMatthew Knepley s->numFields = 0; 2030*ea844a1aSMatthew Knepley s->clObj = NULL; 2031*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2032*ea844a1aSMatthew Knepley } 2033*ea844a1aSMatthew Knepley 2034*ea844a1aSMatthew Knepley /*@ 2035*ea844a1aSMatthew Knepley PetscSectionDestroy - Frees a section object and frees its range if that exists. 2036*ea844a1aSMatthew Knepley 2037*ea844a1aSMatthew Knepley Not collective 2038*ea844a1aSMatthew Knepley 2039*ea844a1aSMatthew Knepley Input Parameters: 2040*ea844a1aSMatthew Knepley . s - the PetscSection 2041*ea844a1aSMatthew Knepley 2042*ea844a1aSMatthew Knepley Level: beginner 2043*ea844a1aSMatthew Knepley 2044*ea844a1aSMatthew Knepley .seealso: PetscSection, PetscSectionCreate() 2045*ea844a1aSMatthew Knepley @*/ 2046*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionDestroy(PetscSection *s) 2047*ea844a1aSMatthew Knepley { 2048*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2049*ea844a1aSMatthew Knepley 2050*ea844a1aSMatthew Knepley PetscFunctionBegin; 2051*ea844a1aSMatthew Knepley if (!*s) PetscFunctionReturn(0); 2052*ea844a1aSMatthew Knepley PetscValidHeaderSpecific((*s),PETSC_SECTION_CLASSID,1); 2053*ea844a1aSMatthew Knepley if (--((PetscObject)(*s))->refct > 0) { 2054*ea844a1aSMatthew Knepley *s = NULL; 2055*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2056*ea844a1aSMatthew Knepley } 2057*ea844a1aSMatthew Knepley ierr = PetscSectionReset(*s);CHKERRQ(ierr); 2058*ea844a1aSMatthew Knepley ierr = PetscHeaderDestroy(s);CHKERRQ(ierr); 2059*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2060*ea844a1aSMatthew Knepley } 2061*ea844a1aSMatthew Knepley 2062*ea844a1aSMatthew Knepley PetscErrorCode VecIntGetValuesSection(PetscInt *baseArray, PetscSection s, PetscInt point, const PetscInt **values) 2063*ea844a1aSMatthew Knepley { 2064*ea844a1aSMatthew Knepley const PetscInt p = point - s->pStart; 2065*ea844a1aSMatthew Knepley 2066*ea844a1aSMatthew Knepley PetscFunctionBegin; 2067*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2); 2068*ea844a1aSMatthew Knepley *values = &baseArray[s->atlasOff[p]]; 2069*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2070*ea844a1aSMatthew Knepley } 2071*ea844a1aSMatthew Knepley 2072*ea844a1aSMatthew Knepley PetscErrorCode VecIntSetValuesSection(PetscInt *baseArray, PetscSection s, PetscInt point, const PetscInt values[], InsertMode mode) 2073*ea844a1aSMatthew Knepley { 2074*ea844a1aSMatthew Knepley PetscInt *array; 2075*ea844a1aSMatthew Knepley const PetscInt p = point - s->pStart; 2076*ea844a1aSMatthew Knepley const PetscInt orientation = 0; /* Needs to be included for use in closure operations */ 2077*ea844a1aSMatthew Knepley PetscInt cDim = 0; 2078*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2079*ea844a1aSMatthew Knepley 2080*ea844a1aSMatthew Knepley PetscFunctionBegin; 2081*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 2); 2082*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cDim);CHKERRQ(ierr); 2083*ea844a1aSMatthew Knepley array = &baseArray[s->atlasOff[p]]; 2084*ea844a1aSMatthew Knepley if (!cDim) { 2085*ea844a1aSMatthew Knepley if (orientation >= 0) { 2086*ea844a1aSMatthew Knepley const PetscInt dim = s->atlasDof[p]; 2087*ea844a1aSMatthew Knepley PetscInt i; 2088*ea844a1aSMatthew Knepley 2089*ea844a1aSMatthew Knepley if (mode == INSERT_VALUES) { 2090*ea844a1aSMatthew Knepley for (i = 0; i < dim; ++i) array[i] = values[i]; 2091*ea844a1aSMatthew Knepley } else { 2092*ea844a1aSMatthew Knepley for (i = 0; i < dim; ++i) array[i] += values[i]; 2093*ea844a1aSMatthew Knepley } 2094*ea844a1aSMatthew Knepley } else { 2095*ea844a1aSMatthew Knepley PetscInt offset = 0; 2096*ea844a1aSMatthew Knepley PetscInt j = -1, field, i; 2097*ea844a1aSMatthew Knepley 2098*ea844a1aSMatthew Knepley for (field = 0; field < s->numFields; ++field) { 2099*ea844a1aSMatthew Knepley const PetscInt dim = s->field[field]->atlasDof[p]; 2100*ea844a1aSMatthew Knepley 2101*ea844a1aSMatthew Knepley for (i = dim-1; i >= 0; --i) array[++j] = values[i+offset]; 2102*ea844a1aSMatthew Knepley offset += dim; 2103*ea844a1aSMatthew Knepley } 2104*ea844a1aSMatthew Knepley } 2105*ea844a1aSMatthew Knepley } else { 2106*ea844a1aSMatthew Knepley if (orientation >= 0) { 2107*ea844a1aSMatthew Knepley const PetscInt dim = s->atlasDof[p]; 2108*ea844a1aSMatthew Knepley PetscInt cInd = 0, i; 2109*ea844a1aSMatthew Knepley const PetscInt *cDof; 2110*ea844a1aSMatthew Knepley 2111*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s, point, &cDof);CHKERRQ(ierr); 2112*ea844a1aSMatthew Knepley if (mode == INSERT_VALUES) { 2113*ea844a1aSMatthew Knepley for (i = 0; i < dim; ++i) { 2114*ea844a1aSMatthew Knepley if ((cInd < cDim) && (i == cDof[cInd])) {++cInd; continue;} 2115*ea844a1aSMatthew Knepley array[i] = values[i]; 2116*ea844a1aSMatthew Knepley } 2117*ea844a1aSMatthew Knepley } else { 2118*ea844a1aSMatthew Knepley for (i = 0; i < dim; ++i) { 2119*ea844a1aSMatthew Knepley if ((cInd < cDim) && (i == cDof[cInd])) {++cInd; continue;} 2120*ea844a1aSMatthew Knepley array[i] += values[i]; 2121*ea844a1aSMatthew Knepley } 2122*ea844a1aSMatthew Knepley } 2123*ea844a1aSMatthew Knepley } else { 2124*ea844a1aSMatthew Knepley const PetscInt *cDof; 2125*ea844a1aSMatthew Knepley PetscInt offset = 0; 2126*ea844a1aSMatthew Knepley PetscInt cOffset = 0; 2127*ea844a1aSMatthew Knepley PetscInt j = 0, field; 2128*ea844a1aSMatthew Knepley 2129*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s, point, &cDof);CHKERRQ(ierr); 2130*ea844a1aSMatthew Knepley for (field = 0; field < s->numFields; ++field) { 2131*ea844a1aSMatthew Knepley const PetscInt dim = s->field[field]->atlasDof[p]; /* PetscSectionGetFieldDof() */ 2132*ea844a1aSMatthew Knepley const PetscInt tDim = s->field[field]->bc->atlasDof[p]; /* PetscSectionGetFieldConstraintDof() */ 2133*ea844a1aSMatthew Knepley const PetscInt sDim = dim - tDim; 2134*ea844a1aSMatthew Knepley PetscInt cInd = 0, i,k; 2135*ea844a1aSMatthew Knepley 2136*ea844a1aSMatthew Knepley for (i = 0, k = dim+offset-1; i < dim; ++i, ++j, --k) { 2137*ea844a1aSMatthew Knepley if ((cInd < sDim) && (j == cDof[cInd+cOffset])) {++cInd; continue;} 2138*ea844a1aSMatthew Knepley array[j] = values[k]; 2139*ea844a1aSMatthew Knepley } 2140*ea844a1aSMatthew Knepley offset += dim; 2141*ea844a1aSMatthew Knepley cOffset += dim - tDim; 2142*ea844a1aSMatthew Knepley } 2143*ea844a1aSMatthew Knepley } 2144*ea844a1aSMatthew Knepley } 2145*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2146*ea844a1aSMatthew Knepley } 2147*ea844a1aSMatthew Knepley 2148*ea844a1aSMatthew Knepley /*@C 2149*ea844a1aSMatthew Knepley PetscSectionHasConstraints - Determine whether a section has constrained dofs 2150*ea844a1aSMatthew Knepley 2151*ea844a1aSMatthew Knepley Not collective 2152*ea844a1aSMatthew Knepley 2153*ea844a1aSMatthew Knepley Input Parameter: 2154*ea844a1aSMatthew Knepley . s - The PetscSection 2155*ea844a1aSMatthew Knepley 2156*ea844a1aSMatthew Knepley Output Parameter: 2157*ea844a1aSMatthew Knepley . hasConstraints - flag indicating that the section has constrained dofs 2158*ea844a1aSMatthew Knepley 2159*ea844a1aSMatthew Knepley Level: intermediate 2160*ea844a1aSMatthew Knepley 2161*ea844a1aSMatthew Knepley .seealso: PetscSectionSetConstraintIndices(), PetscSectionGetConstraintDof(), PetscSection 2162*ea844a1aSMatthew Knepley @*/ 2163*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionHasConstraints(PetscSection s, PetscBool *hasConstraints) 2164*ea844a1aSMatthew Knepley { 2165*ea844a1aSMatthew Knepley PetscFunctionBegin; 2166*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2167*ea844a1aSMatthew Knepley PetscValidPointer(hasConstraints, 2); 2168*ea844a1aSMatthew Knepley *hasConstraints = s->bc ? PETSC_TRUE : PETSC_FALSE; 2169*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2170*ea844a1aSMatthew Knepley } 2171*ea844a1aSMatthew Knepley 2172*ea844a1aSMatthew Knepley /*@C 2173*ea844a1aSMatthew Knepley PetscSectionGetConstraintIndices - Get the point dof numbers, in [0, dof), which are constrained 2174*ea844a1aSMatthew Knepley 2175*ea844a1aSMatthew Knepley Not collective 2176*ea844a1aSMatthew Knepley 2177*ea844a1aSMatthew Knepley Input Parameters: 2178*ea844a1aSMatthew Knepley + s - The PetscSection 2179*ea844a1aSMatthew Knepley - point - The point 2180*ea844a1aSMatthew Knepley 2181*ea844a1aSMatthew Knepley Output Parameter: 2182*ea844a1aSMatthew Knepley . indices - The constrained dofs 2183*ea844a1aSMatthew Knepley 2184*ea844a1aSMatthew Knepley Note: In Fortran, you call PetscSectionGetConstraintIndicesF90() and PetscSectionRestoreConstraintIndicesF90() 2185*ea844a1aSMatthew Knepley 2186*ea844a1aSMatthew Knepley Level: intermediate 2187*ea844a1aSMatthew Knepley 2188*ea844a1aSMatthew Knepley .seealso: PetscSectionSetConstraintIndices(), PetscSectionGetConstraintDof(), PetscSection 2189*ea844a1aSMatthew Knepley @*/ 2190*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetConstraintIndices(PetscSection s, PetscInt point, const PetscInt **indices) 2191*ea844a1aSMatthew Knepley { 2192*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2193*ea844a1aSMatthew Knepley 2194*ea844a1aSMatthew Knepley PetscFunctionBegin; 2195*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2196*ea844a1aSMatthew Knepley if (s->bc) { 2197*ea844a1aSMatthew Knepley ierr = VecIntGetValuesSection(s->bcIndices, s->bc, point, indices);CHKERRQ(ierr); 2198*ea844a1aSMatthew Knepley } else *indices = NULL; 2199*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2200*ea844a1aSMatthew Knepley } 2201*ea844a1aSMatthew Knepley 2202*ea844a1aSMatthew Knepley /*@C 2203*ea844a1aSMatthew Knepley PetscSectionSetConstraintIndices - Set the point dof numbers, in [0, dof), which are constrained 2204*ea844a1aSMatthew Knepley 2205*ea844a1aSMatthew Knepley Not collective 2206*ea844a1aSMatthew Knepley 2207*ea844a1aSMatthew Knepley Input Parameters: 2208*ea844a1aSMatthew Knepley + s - The PetscSection 2209*ea844a1aSMatthew Knepley . point - The point 2210*ea844a1aSMatthew Knepley - indices - The constrained dofs 2211*ea844a1aSMatthew Knepley 2212*ea844a1aSMatthew Knepley Note: The Fortran is PetscSectionSetConstraintIndicesF90() 2213*ea844a1aSMatthew Knepley 2214*ea844a1aSMatthew Knepley Level: intermediate 2215*ea844a1aSMatthew Knepley 2216*ea844a1aSMatthew Knepley .seealso: PetscSectionGetConstraintIndices(), PetscSectionGetConstraintDof(), PetscSection 2217*ea844a1aSMatthew Knepley @*/ 2218*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetConstraintIndices(PetscSection s, PetscInt point, const PetscInt indices[]) 2219*ea844a1aSMatthew Knepley { 2220*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2221*ea844a1aSMatthew Knepley 2222*ea844a1aSMatthew Knepley PetscFunctionBegin; 2223*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2224*ea844a1aSMatthew Knepley if (s->bc) { 2225*ea844a1aSMatthew Knepley ierr = VecIntSetValuesSection(s->bcIndices, s->bc, point, indices, INSERT_VALUES);CHKERRQ(ierr); 2226*ea844a1aSMatthew Knepley } 2227*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2228*ea844a1aSMatthew Knepley } 2229*ea844a1aSMatthew Knepley 2230*ea844a1aSMatthew Knepley /*@C 2231*ea844a1aSMatthew Knepley PetscSectionGetFieldConstraintIndices - Get the field dof numbers, in [0, fdof), which are constrained 2232*ea844a1aSMatthew Knepley 2233*ea844a1aSMatthew Knepley Not collective 2234*ea844a1aSMatthew Knepley 2235*ea844a1aSMatthew Knepley Input Parameters: 2236*ea844a1aSMatthew Knepley + s - The PetscSection 2237*ea844a1aSMatthew Knepley .field - The field number 2238*ea844a1aSMatthew Knepley - point - The point 2239*ea844a1aSMatthew Knepley 2240*ea844a1aSMatthew Knepley Output Parameter: 2241*ea844a1aSMatthew Knepley . indices - The constrained dofs 2242*ea844a1aSMatthew Knepley 2243*ea844a1aSMatthew Knepley Note: In Fortran, you call PetscSectionGetFieldConstraintIndicesF90() and PetscSectionRestoreFieldConstraintIndicesF90() 2244*ea844a1aSMatthew Knepley 2245*ea844a1aSMatthew Knepley Level: intermediate 2246*ea844a1aSMatthew Knepley 2247*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldConstraintIndices(), PetscSectionGetConstraintIndices(), PetscSectionGetConstraintDof(), PetscSection 2248*ea844a1aSMatthew Knepley @*/ 2249*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldConstraintIndices(PetscSection s, PetscInt point, PetscInt field, const PetscInt **indices) 2250*ea844a1aSMatthew Knepley { 2251*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2252*ea844a1aSMatthew Knepley 2253*ea844a1aSMatthew Knepley PetscFunctionBegin; 2254*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2255*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 2256*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s->field[field], point, indices);CHKERRQ(ierr); 2257*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2258*ea844a1aSMatthew Knepley } 2259*ea844a1aSMatthew Knepley 2260*ea844a1aSMatthew Knepley /*@C 2261*ea844a1aSMatthew Knepley PetscSectionSetFieldConstraintIndices - Set the field dof numbers, in [0, fdof), which are constrained 2262*ea844a1aSMatthew Knepley 2263*ea844a1aSMatthew Knepley Not collective 2264*ea844a1aSMatthew Knepley 2265*ea844a1aSMatthew Knepley Input Parameters: 2266*ea844a1aSMatthew Knepley + s - The PetscSection 2267*ea844a1aSMatthew Knepley . point - The point 2268*ea844a1aSMatthew Knepley . field - The field number 2269*ea844a1aSMatthew Knepley - indices - The constrained dofs 2270*ea844a1aSMatthew Knepley 2271*ea844a1aSMatthew Knepley Note: The Fortran is PetscSectionSetFieldConstraintIndicesF90() 2272*ea844a1aSMatthew Knepley 2273*ea844a1aSMatthew Knepley Level: intermediate 2274*ea844a1aSMatthew Knepley 2275*ea844a1aSMatthew Knepley .seealso: PetscSectionSetConstraintIndices(), PetscSectionGetFieldConstraintIndices(), PetscSectionGetConstraintDof(), PetscSection 2276*ea844a1aSMatthew Knepley @*/ 2277*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldConstraintIndices(PetscSection s, PetscInt point, PetscInt field, const PetscInt indices[]) 2278*ea844a1aSMatthew Knepley { 2279*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2280*ea844a1aSMatthew Knepley 2281*ea844a1aSMatthew Knepley PetscFunctionBegin; 2282*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2283*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 2284*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(s->field[field], point, indices);CHKERRQ(ierr); 2285*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2286*ea844a1aSMatthew Knepley } 2287*ea844a1aSMatthew Knepley 2288*ea844a1aSMatthew Knepley /*@ 2289*ea844a1aSMatthew Knepley PetscSectionPermute - Reorder the section according to the input point permutation 2290*ea844a1aSMatthew Knepley 2291*ea844a1aSMatthew Knepley Collective on PetscSection 2292*ea844a1aSMatthew Knepley 2293*ea844a1aSMatthew Knepley Input Parameter: 2294*ea844a1aSMatthew Knepley + section - The PetscSection object 2295*ea844a1aSMatthew Knepley - perm - The point permutation, old point p becomes new point perm[p] 2296*ea844a1aSMatthew Knepley 2297*ea844a1aSMatthew Knepley Output Parameter: 2298*ea844a1aSMatthew Knepley . sectionNew - The permuted PetscSection 2299*ea844a1aSMatthew Knepley 2300*ea844a1aSMatthew Knepley Level: intermediate 2301*ea844a1aSMatthew Knepley 2302*ea844a1aSMatthew Knepley .seealso: MatPermute() 2303*ea844a1aSMatthew Knepley @*/ 2304*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionPermute(PetscSection section, IS permutation, PetscSection *sectionNew) 2305*ea844a1aSMatthew Knepley { 2306*ea844a1aSMatthew Knepley PetscSection s = section, sNew; 2307*ea844a1aSMatthew Knepley const PetscInt *perm; 2308*ea844a1aSMatthew Knepley PetscInt numFields, f, numPoints, pStart, pEnd, p; 2309*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2310*ea844a1aSMatthew Knepley 2311*ea844a1aSMatthew Knepley PetscFunctionBegin; 2312*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 1); 2313*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 2314*ea844a1aSMatthew Knepley PetscValidPointer(sectionNew, 3); 2315*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), &sNew);CHKERRQ(ierr); 2316*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(s, &numFields);CHKERRQ(ierr); 2317*ea844a1aSMatthew Knepley if (numFields) {ierr = PetscSectionSetNumFields(sNew, numFields);CHKERRQ(ierr);} 2318*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 2319*ea844a1aSMatthew Knepley const char *name; 2320*ea844a1aSMatthew Knepley PetscInt numComp; 2321*ea844a1aSMatthew Knepley 2322*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldName(s, f, &name);CHKERRQ(ierr); 2323*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldName(sNew, f, name);CHKERRQ(ierr); 2324*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(s, f, &numComp);CHKERRQ(ierr); 2325*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(sNew, f, numComp);CHKERRQ(ierr); 2326*ea844a1aSMatthew Knepley } 2327*ea844a1aSMatthew Knepley ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 2328*ea844a1aSMatthew Knepley ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 2329*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 2330*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(sNew, pStart, pEnd);CHKERRQ(ierr); 2331*ea844a1aSMatthew Knepley if (numPoints < pEnd) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Permutation size %D is less than largest Section point %D", numPoints, pEnd); 2332*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 2333*ea844a1aSMatthew Knepley PetscInt dof, cdof; 2334*ea844a1aSMatthew Knepley 2335*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 2336*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(sNew, perm[p], dof);CHKERRQ(ierr); 2337*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2338*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetConstraintDof(sNew, perm[p], cdof);CHKERRQ(ierr);} 2339*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 2340*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr); 2341*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldDof(sNew, perm[p], f, dof);CHKERRQ(ierr); 2342*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s, p, f, &cdof);CHKERRQ(ierr); 2343*ea844a1aSMatthew Knepley if (cdof) {ierr = PetscSectionSetFieldConstraintDof(sNew, perm[p], f, cdof);CHKERRQ(ierr);} 2344*ea844a1aSMatthew Knepley } 2345*ea844a1aSMatthew Knepley } 2346*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(sNew);CHKERRQ(ierr); 2347*ea844a1aSMatthew Knepley for (p = pStart; p < pEnd; ++p) { 2348*ea844a1aSMatthew Knepley const PetscInt *cind; 2349*ea844a1aSMatthew Knepley PetscInt cdof; 2350*ea844a1aSMatthew Knepley 2351*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2352*ea844a1aSMatthew Knepley if (cdof) { 2353*ea844a1aSMatthew Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cind);CHKERRQ(ierr); 2354*ea844a1aSMatthew Knepley ierr = PetscSectionSetConstraintIndices(sNew, perm[p], cind);CHKERRQ(ierr); 2355*ea844a1aSMatthew Knepley } 2356*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 2357*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintDof(s, p, f, &cdof);CHKERRQ(ierr); 2358*ea844a1aSMatthew Knepley if (cdof) { 2359*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldConstraintIndices(s, p, f, &cind);CHKERRQ(ierr); 2360*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldConstraintIndices(sNew, perm[p], f, cind);CHKERRQ(ierr); 2361*ea844a1aSMatthew Knepley } 2362*ea844a1aSMatthew Knepley } 2363*ea844a1aSMatthew Knepley } 2364*ea844a1aSMatthew Knepley ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 2365*ea844a1aSMatthew Knepley *sectionNew = sNew; 2366*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2367*ea844a1aSMatthew Knepley } 2368*ea844a1aSMatthew Knepley 2369*ea844a1aSMatthew Knepley /* TODO: the next three functions should be moved to sf/utils */ 2370*ea844a1aSMatthew Knepley #include <petsc/private/sfimpl.h> 2371*ea844a1aSMatthew Knepley 2372*ea844a1aSMatthew Knepley /*@C 2373*ea844a1aSMatthew Knepley PetscSFDistributeSection - Create a new PetscSection reorganized, moving from the root to the leaves of the SF 2374*ea844a1aSMatthew Knepley 2375*ea844a1aSMatthew Knepley Collective on sf 2376*ea844a1aSMatthew Knepley 2377*ea844a1aSMatthew Knepley Input Parameters: 2378*ea844a1aSMatthew Knepley + sf - The SF 2379*ea844a1aSMatthew Knepley - rootSection - Section defined on root space 2380*ea844a1aSMatthew Knepley 2381*ea844a1aSMatthew Knepley Output Parameters: 2382*ea844a1aSMatthew Knepley + remoteOffsets - root offsets in leaf storage, or NULL 2383*ea844a1aSMatthew Knepley - leafSection - Section defined on the leaf space 2384*ea844a1aSMatthew Knepley 2385*ea844a1aSMatthew Knepley Level: advanced 2386*ea844a1aSMatthew Knepley 2387*ea844a1aSMatthew Knepley .seealso: PetscSFCreate() 2388*ea844a1aSMatthew Knepley @*/ 2389*ea844a1aSMatthew Knepley PetscErrorCode PetscSFDistributeSection(PetscSF sf, PetscSection rootSection, PetscInt **remoteOffsets, PetscSection leafSection) 2390*ea844a1aSMatthew Knepley { 2391*ea844a1aSMatthew Knepley PetscSF embedSF; 2392*ea844a1aSMatthew Knepley const PetscInt *indices; 2393*ea844a1aSMatthew Knepley IS selected; 2394*ea844a1aSMatthew Knepley PetscInt numFields, nroots, rpStart, rpEnd, lpStart = PETSC_MAX_INT, lpEnd = -1, f; 2395*ea844a1aSMatthew Knepley PetscBool sub,lsub; 2396*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2397*ea844a1aSMatthew Knepley 2398*ea844a1aSMatthew Knepley PetscFunctionBegin; 2399*ea844a1aSMatthew Knepley ierr = PetscLogEventBegin(PETSCSF_DistSect,sf,0,0,0);CHKERRQ(ierr); 2400*ea844a1aSMatthew Knepley ierr = PetscSectionGetNumFields(rootSection, &numFields);CHKERRQ(ierr); 2401*ea844a1aSMatthew Knepley if (numFields) {ierr = PetscSectionSetNumFields(leafSection, numFields);CHKERRQ(ierr);} 2402*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 2403*ea844a1aSMatthew Knepley PetscInt numComp = 0; 2404*ea844a1aSMatthew Knepley ierr = PetscSectionGetFieldComponents(rootSection, f, &numComp);CHKERRQ(ierr); 2405*ea844a1aSMatthew Knepley ierr = PetscSectionSetFieldComponents(leafSection, f, numComp);CHKERRQ(ierr); 2406*ea844a1aSMatthew Knepley } 2407*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(rootSection, &rpStart, &rpEnd);CHKERRQ(ierr); 2408*ea844a1aSMatthew Knepley ierr = PetscSFGetGraph(sf,&nroots,NULL,NULL,NULL);CHKERRQ(ierr); 2409*ea844a1aSMatthew Knepley rpEnd = PetscMin(rpEnd,nroots); 2410*ea844a1aSMatthew Knepley rpEnd = PetscMax(rpStart,rpEnd); 2411*ea844a1aSMatthew Knepley /* see if we can avoid creating the embedded SF, since it can cost more than an allreduce */ 2412*ea844a1aSMatthew Knepley lsub = (PetscBool)(nroots != rpEnd - rpStart); 2413*ea844a1aSMatthew Knepley ierr = MPIU_Allreduce(&lsub,&sub,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 2414*ea844a1aSMatthew Knepley if (sub) { 2415*ea844a1aSMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF, rpEnd - rpStart, rpStart, 1, &selected);CHKERRQ(ierr); 2416*ea844a1aSMatthew Knepley ierr = ISGetIndices(selected, &indices);CHKERRQ(ierr); 2417*ea844a1aSMatthew Knepley ierr = PetscSFCreateEmbeddedSF(sf, rpEnd - rpStart, indices, &embedSF);CHKERRQ(ierr); 2418*ea844a1aSMatthew Knepley ierr = ISRestoreIndices(selected, &indices);CHKERRQ(ierr); 2419*ea844a1aSMatthew Knepley ierr = ISDestroy(&selected);CHKERRQ(ierr); 2420*ea844a1aSMatthew Knepley } else { 2421*ea844a1aSMatthew Knepley ierr = PetscObjectReference((PetscObject)sf);CHKERRQ(ierr); 2422*ea844a1aSMatthew Knepley embedSF = sf; 2423*ea844a1aSMatthew Knepley } 2424*ea844a1aSMatthew Knepley ierr = PetscSFGetLeafRange(embedSF, &lpStart, &lpEnd);CHKERRQ(ierr); 2425*ea844a1aSMatthew Knepley lpEnd++; 2426*ea844a1aSMatthew Knepley 2427*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(leafSection, lpStart, lpEnd);CHKERRQ(ierr); 2428*ea844a1aSMatthew Knepley /* Could fuse these at the cost of a copy and extra allocation */ 2429*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(embedSF, MPIU_INT, &rootSection->atlasDof[-rpStart], &leafSection->atlasDof[-lpStart]);CHKERRQ(ierr); 2430*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(embedSF, MPIU_INT, &rootSection->atlasDof[-rpStart], &leafSection->atlasDof[-lpStart]);CHKERRQ(ierr); 2431*ea844a1aSMatthew Knepley for (f = 0; f < numFields; ++f) { 2432*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(embedSF, MPIU_INT, &rootSection->field[f]->atlasDof[-rpStart], &leafSection->field[f]->atlasDof[-lpStart]);CHKERRQ(ierr); 2433*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(embedSF, MPIU_INT, &rootSection->field[f]->atlasDof[-rpStart], &leafSection->field[f]->atlasDof[-lpStart]);CHKERRQ(ierr); 2434*ea844a1aSMatthew Knepley } 2435*ea844a1aSMatthew Knepley if (remoteOffsets) { 2436*ea844a1aSMatthew Knepley ierr = PetscMalloc1(lpEnd - lpStart, remoteOffsets);CHKERRQ(ierr); 2437*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(embedSF, MPIU_INT, &rootSection->atlasOff[-rpStart], &(*remoteOffsets)[-lpStart]);CHKERRQ(ierr); 2438*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(embedSF, MPIU_INT, &rootSection->atlasOff[-rpStart], &(*remoteOffsets)[-lpStart]);CHKERRQ(ierr); 2439*ea844a1aSMatthew Knepley } 2440*ea844a1aSMatthew Knepley ierr = PetscSFDestroy(&embedSF);CHKERRQ(ierr); 2441*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(leafSection);CHKERRQ(ierr); 2442*ea844a1aSMatthew Knepley ierr = PetscLogEventEnd(PETSCSF_DistSect,sf,0,0,0);CHKERRQ(ierr); 2443*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2444*ea844a1aSMatthew Knepley } 2445*ea844a1aSMatthew Knepley 2446*ea844a1aSMatthew Knepley /*@C 2447*ea844a1aSMatthew Knepley PetscSFCreateRemoteOffsets - Create offsets for point data on remote processes 2448*ea844a1aSMatthew Knepley 2449*ea844a1aSMatthew Knepley Collective on sf 2450*ea844a1aSMatthew Knepley 2451*ea844a1aSMatthew Knepley Input Parameters: 2452*ea844a1aSMatthew Knepley + sf - The SF 2453*ea844a1aSMatthew Knepley . rootSection - Data layout of remote points for outgoing data (this is layout for SF roots) 2454*ea844a1aSMatthew Knepley - leafSection - Data layout of local points for incoming data (this is layout for SF leaves) 2455*ea844a1aSMatthew Knepley 2456*ea844a1aSMatthew Knepley Output Parameter: 2457*ea844a1aSMatthew Knepley . remoteOffsets - Offsets for point data on remote processes (these are offsets from the root section), or NULL 2458*ea844a1aSMatthew Knepley 2459*ea844a1aSMatthew Knepley Level: developer 2460*ea844a1aSMatthew Knepley 2461*ea844a1aSMatthew Knepley .seealso: PetscSFCreate() 2462*ea844a1aSMatthew Knepley @*/ 2463*ea844a1aSMatthew Knepley PetscErrorCode PetscSFCreateRemoteOffsets(PetscSF sf, PetscSection rootSection, PetscSection leafSection, PetscInt **remoteOffsets) 2464*ea844a1aSMatthew Knepley { 2465*ea844a1aSMatthew Knepley PetscSF embedSF; 2466*ea844a1aSMatthew Knepley const PetscInt *indices; 2467*ea844a1aSMatthew Knepley IS selected; 2468*ea844a1aSMatthew Knepley PetscInt numRoots, rpStart = 0, rpEnd = 0, lpStart = 0, lpEnd = 0; 2469*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2470*ea844a1aSMatthew Knepley 2471*ea844a1aSMatthew Knepley PetscFunctionBegin; 2472*ea844a1aSMatthew Knepley *remoteOffsets = NULL; 2473*ea844a1aSMatthew Knepley ierr = PetscSFGetGraph(sf, &numRoots, NULL, NULL, NULL);CHKERRQ(ierr); 2474*ea844a1aSMatthew Knepley if (numRoots < 0) PetscFunctionReturn(0); 2475*ea844a1aSMatthew Knepley ierr = PetscLogEventBegin(PETSCSF_RemoteOff,sf,0,0,0);CHKERRQ(ierr); 2476*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(rootSection, &rpStart, &rpEnd);CHKERRQ(ierr); 2477*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(leafSection, &lpStart, &lpEnd);CHKERRQ(ierr); 2478*ea844a1aSMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF, rpEnd - rpStart, rpStart, 1, &selected);CHKERRQ(ierr); 2479*ea844a1aSMatthew Knepley ierr = ISGetIndices(selected, &indices);CHKERRQ(ierr); 2480*ea844a1aSMatthew Knepley ierr = PetscSFCreateEmbeddedSF(sf, rpEnd - rpStart, indices, &embedSF);CHKERRQ(ierr); 2481*ea844a1aSMatthew Knepley ierr = ISRestoreIndices(selected, &indices);CHKERRQ(ierr); 2482*ea844a1aSMatthew Knepley ierr = ISDestroy(&selected);CHKERRQ(ierr); 2483*ea844a1aSMatthew Knepley ierr = PetscCalloc1(lpEnd - lpStart, remoteOffsets);CHKERRQ(ierr); 2484*ea844a1aSMatthew Knepley ierr = PetscSFBcastBegin(embedSF, MPIU_INT, &rootSection->atlasOff[-rpStart], &(*remoteOffsets)[-lpStart]);CHKERRQ(ierr); 2485*ea844a1aSMatthew Knepley ierr = PetscSFBcastEnd(embedSF, MPIU_INT, &rootSection->atlasOff[-rpStart], &(*remoteOffsets)[-lpStart]);CHKERRQ(ierr); 2486*ea844a1aSMatthew Knepley ierr = PetscSFDestroy(&embedSF);CHKERRQ(ierr); 2487*ea844a1aSMatthew Knepley ierr = PetscLogEventEnd(PETSCSF_RemoteOff,sf,0,0,0);CHKERRQ(ierr); 2488*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2489*ea844a1aSMatthew Knepley } 2490*ea844a1aSMatthew Knepley 2491*ea844a1aSMatthew Knepley /*@C 2492*ea844a1aSMatthew Knepley PetscSFCreateSectionSF - Create an expanded SF of dofs, assuming the input SF relates points 2493*ea844a1aSMatthew Knepley 2494*ea844a1aSMatthew Knepley Collective on sf 2495*ea844a1aSMatthew Knepley 2496*ea844a1aSMatthew Knepley Input Parameters: 2497*ea844a1aSMatthew Knepley + sf - The SF 2498*ea844a1aSMatthew Knepley . rootSection - Data layout of remote points for outgoing data (this is usually the serial section) 2499*ea844a1aSMatthew Knepley . remoteOffsets - Offsets for point data on remote processes (these are offsets from the root section), or NULL 2500*ea844a1aSMatthew Knepley - leafSection - Data layout of local points for incoming data (this is the distributed section) 2501*ea844a1aSMatthew Knepley 2502*ea844a1aSMatthew Knepley Output Parameters: 2503*ea844a1aSMatthew Knepley - sectionSF - The new SF 2504*ea844a1aSMatthew Knepley 2505*ea844a1aSMatthew Knepley Note: Either rootSection or remoteOffsets can be specified 2506*ea844a1aSMatthew Knepley 2507*ea844a1aSMatthew Knepley Level: advanced 2508*ea844a1aSMatthew Knepley 2509*ea844a1aSMatthew Knepley .seealso: PetscSFCreate() 2510*ea844a1aSMatthew Knepley @*/ 2511*ea844a1aSMatthew Knepley PetscErrorCode PetscSFCreateSectionSF(PetscSF sf, PetscSection rootSection, PetscInt remoteOffsets[], PetscSection leafSection, PetscSF *sectionSF) 2512*ea844a1aSMatthew Knepley { 2513*ea844a1aSMatthew Knepley MPI_Comm comm; 2514*ea844a1aSMatthew Knepley const PetscInt *localPoints; 2515*ea844a1aSMatthew Knepley const PetscSFNode *remotePoints; 2516*ea844a1aSMatthew Knepley PetscInt lpStart, lpEnd; 2517*ea844a1aSMatthew Knepley PetscInt numRoots, numSectionRoots, numPoints, numIndices = 0; 2518*ea844a1aSMatthew Knepley PetscInt *localIndices; 2519*ea844a1aSMatthew Knepley PetscSFNode *remoteIndices; 2520*ea844a1aSMatthew Knepley PetscInt i, ind; 2521*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2522*ea844a1aSMatthew Knepley 2523*ea844a1aSMatthew Knepley PetscFunctionBegin; 2524*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 2525*ea844a1aSMatthew Knepley PetscValidPointer(rootSection,2); 2526*ea844a1aSMatthew Knepley /* Cannot check PetscValidIntPointer(remoteOffsets,3) because it can be NULL if sf does not reference any points in leafSection */ 2527*ea844a1aSMatthew Knepley PetscValidPointer(leafSection,4); 2528*ea844a1aSMatthew Knepley PetscValidPointer(sectionSF,5); 2529*ea844a1aSMatthew Knepley ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 2530*ea844a1aSMatthew Knepley ierr = PetscSFCreate(comm, sectionSF);CHKERRQ(ierr); 2531*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(leafSection, &lpStart, &lpEnd);CHKERRQ(ierr); 2532*ea844a1aSMatthew Knepley ierr = PetscSectionGetStorageSize(rootSection, &numSectionRoots);CHKERRQ(ierr); 2533*ea844a1aSMatthew Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numPoints, &localPoints, &remotePoints);CHKERRQ(ierr); 2534*ea844a1aSMatthew Knepley if (numRoots < 0) PetscFunctionReturn(0); 2535*ea844a1aSMatthew Knepley ierr = PetscLogEventBegin(PETSCSF_SectSF,sf,0,0,0);CHKERRQ(ierr); 2536*ea844a1aSMatthew Knepley for (i = 0; i < numPoints; ++i) { 2537*ea844a1aSMatthew Knepley PetscInt localPoint = localPoints ? localPoints[i] : i; 2538*ea844a1aSMatthew Knepley PetscInt dof; 2539*ea844a1aSMatthew Knepley 2540*ea844a1aSMatthew Knepley if ((localPoint >= lpStart) && (localPoint < lpEnd)) { 2541*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(leafSection, localPoint, &dof);CHKERRQ(ierr); 2542*ea844a1aSMatthew Knepley numIndices += dof; 2543*ea844a1aSMatthew Knepley } 2544*ea844a1aSMatthew Knepley } 2545*ea844a1aSMatthew Knepley ierr = PetscMalloc1(numIndices, &localIndices);CHKERRQ(ierr); 2546*ea844a1aSMatthew Knepley ierr = PetscMalloc1(numIndices, &remoteIndices);CHKERRQ(ierr); 2547*ea844a1aSMatthew Knepley /* Create new index graph */ 2548*ea844a1aSMatthew Knepley for (i = 0, ind = 0; i < numPoints; ++i) { 2549*ea844a1aSMatthew Knepley PetscInt localPoint = localPoints ? localPoints[i] : i; 2550*ea844a1aSMatthew Knepley PetscInt rank = remotePoints[i].rank; 2551*ea844a1aSMatthew Knepley 2552*ea844a1aSMatthew Knepley if ((localPoint >= lpStart) && (localPoint < lpEnd)) { 2553*ea844a1aSMatthew Knepley PetscInt remoteOffset = remoteOffsets[localPoint-lpStart]; 2554*ea844a1aSMatthew Knepley PetscInt loff, dof, d; 2555*ea844a1aSMatthew Knepley 2556*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(leafSection, localPoint, &loff);CHKERRQ(ierr); 2557*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(leafSection, localPoint, &dof);CHKERRQ(ierr); 2558*ea844a1aSMatthew Knepley for (d = 0; d < dof; ++d, ++ind) { 2559*ea844a1aSMatthew Knepley localIndices[ind] = loff+d; 2560*ea844a1aSMatthew Knepley remoteIndices[ind].rank = rank; 2561*ea844a1aSMatthew Knepley remoteIndices[ind].index = remoteOffset+d; 2562*ea844a1aSMatthew Knepley } 2563*ea844a1aSMatthew Knepley } 2564*ea844a1aSMatthew Knepley } 2565*ea844a1aSMatthew Knepley if (numIndices != ind) SETERRQ2(comm, PETSC_ERR_PLIB, "Inconsistency in indices, %D should be %D", ind, numIndices); 2566*ea844a1aSMatthew Knepley ierr = PetscSFSetGraph(*sectionSF, numSectionRoots, numIndices, localIndices, PETSC_OWN_POINTER, remoteIndices, PETSC_OWN_POINTER);CHKERRQ(ierr); 2567*ea844a1aSMatthew Knepley ierr = PetscSFSetUp(*sectionSF);CHKERRQ(ierr); 2568*ea844a1aSMatthew Knepley ierr = PetscLogEventEnd(PETSCSF_SectSF,sf,0,0,0);CHKERRQ(ierr); 2569*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2570*ea844a1aSMatthew Knepley } 2571*ea844a1aSMatthew Knepley 2572*ea844a1aSMatthew Knepley /*@ 2573*ea844a1aSMatthew Knepley PetscSectionSetClosureIndex - Set a cache of points in the closure of each point in the section 2574*ea844a1aSMatthew Knepley 2575*ea844a1aSMatthew Knepley Collective on section 2576*ea844a1aSMatthew Knepley 2577*ea844a1aSMatthew Knepley Input Parameters: 2578*ea844a1aSMatthew Knepley + section - The PetscSection 2579*ea844a1aSMatthew Knepley . obj - A PetscObject which serves as the key for this index 2580*ea844a1aSMatthew Knepley . clSection - Section giving the size of the closure of each point 2581*ea844a1aSMatthew Knepley - clPoints - IS giving the points in each closure 2582*ea844a1aSMatthew Knepley 2583*ea844a1aSMatthew Knepley Note: We compress out closure points with no dofs in this section 2584*ea844a1aSMatthew Knepley 2585*ea844a1aSMatthew Knepley Level: advanced 2586*ea844a1aSMatthew Knepley 2587*ea844a1aSMatthew Knepley .seealso: PetscSectionGetClosureIndex(), DMPlexCreateClosureIndex() 2588*ea844a1aSMatthew Knepley @*/ 2589*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetClosureIndex(PetscSection section, PetscObject obj, PetscSection clSection, IS clPoints) 2590*ea844a1aSMatthew Knepley { 2591*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2592*ea844a1aSMatthew Knepley 2593*ea844a1aSMatthew Knepley PetscFunctionBegin; 2594*ea844a1aSMatthew Knepley if (section->clObj != obj) {ierr = PetscFree(section->clPerm);CHKERRQ(ierr);ierr = PetscFree(section->clInvPerm);CHKERRQ(ierr);} 2595*ea844a1aSMatthew Knepley section->clObj = obj; 2596*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(§ion->clSection);CHKERRQ(ierr); 2597*ea844a1aSMatthew Knepley ierr = ISDestroy(§ion->clPoints);CHKERRQ(ierr); 2598*ea844a1aSMatthew Knepley section->clSection = clSection; 2599*ea844a1aSMatthew Knepley section->clPoints = clPoints; 2600*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2601*ea844a1aSMatthew Knepley } 2602*ea844a1aSMatthew Knepley 2603*ea844a1aSMatthew Knepley /*@ 2604*ea844a1aSMatthew Knepley PetscSectionGetClosureIndex - Get the cache of points in the closure of each point in the section 2605*ea844a1aSMatthew Knepley 2606*ea844a1aSMatthew Knepley Collective on section 2607*ea844a1aSMatthew Knepley 2608*ea844a1aSMatthew Knepley Input Parameters: 2609*ea844a1aSMatthew Knepley + section - The PetscSection 2610*ea844a1aSMatthew Knepley - obj - A PetscObject which serves as the key for this index 2611*ea844a1aSMatthew Knepley 2612*ea844a1aSMatthew Knepley Output Parameters: 2613*ea844a1aSMatthew Knepley + clSection - Section giving the size of the closure of each point 2614*ea844a1aSMatthew Knepley - clPoints - IS giving the points in each closure 2615*ea844a1aSMatthew Knepley 2616*ea844a1aSMatthew Knepley Note: We compress out closure points with no dofs in this section 2617*ea844a1aSMatthew Knepley 2618*ea844a1aSMatthew Knepley Level: advanced 2619*ea844a1aSMatthew Knepley 2620*ea844a1aSMatthew Knepley .seealso: PetscSectionSetClosureIndex(), DMPlexCreateClosureIndex() 2621*ea844a1aSMatthew Knepley @*/ 2622*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetClosureIndex(PetscSection section, PetscObject obj, PetscSection *clSection, IS *clPoints) 2623*ea844a1aSMatthew Knepley { 2624*ea844a1aSMatthew Knepley PetscFunctionBegin; 2625*ea844a1aSMatthew Knepley if (section->clObj == obj) { 2626*ea844a1aSMatthew Knepley if (clSection) *clSection = section->clSection; 2627*ea844a1aSMatthew Knepley if (clPoints) *clPoints = section->clPoints; 2628*ea844a1aSMatthew Knepley } else { 2629*ea844a1aSMatthew Knepley if (clSection) *clSection = NULL; 2630*ea844a1aSMatthew Knepley if (clPoints) *clPoints = NULL; 2631*ea844a1aSMatthew Knepley } 2632*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2633*ea844a1aSMatthew Knepley } 2634*ea844a1aSMatthew Knepley 2635*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetClosurePermutation_Internal(PetscSection section, PetscObject obj, PetscInt clSize, PetscCopyMode mode, PetscInt *clPerm) 2636*ea844a1aSMatthew Knepley { 2637*ea844a1aSMatthew Knepley PetscInt i; 2638*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2639*ea844a1aSMatthew Knepley 2640*ea844a1aSMatthew Knepley PetscFunctionBegin; 2641*ea844a1aSMatthew Knepley if (section->clObj != obj) { 2642*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(§ion->clSection);CHKERRQ(ierr); 2643*ea844a1aSMatthew Knepley ierr = ISDestroy(§ion->clPoints);CHKERRQ(ierr); 2644*ea844a1aSMatthew Knepley } 2645*ea844a1aSMatthew Knepley section->clObj = obj; 2646*ea844a1aSMatthew Knepley ierr = PetscFree(section->clPerm);CHKERRQ(ierr); 2647*ea844a1aSMatthew Knepley ierr = PetscFree(section->clInvPerm);CHKERRQ(ierr); 2648*ea844a1aSMatthew Knepley section->clSize = clSize; 2649*ea844a1aSMatthew Knepley if (mode == PETSC_COPY_VALUES) { 2650*ea844a1aSMatthew Knepley ierr = PetscMalloc1(clSize, §ion->clPerm);CHKERRQ(ierr); 2651*ea844a1aSMatthew Knepley ierr = PetscLogObjectMemory((PetscObject) obj, clSize*sizeof(PetscInt));CHKERRQ(ierr); 2652*ea844a1aSMatthew Knepley ierr = PetscArraycpy(section->clPerm, clPerm, clSize);CHKERRQ(ierr); 2653*ea844a1aSMatthew Knepley } else if (mode == PETSC_OWN_POINTER) { 2654*ea844a1aSMatthew Knepley section->clPerm = clPerm; 2655*ea844a1aSMatthew Knepley } else SETERRQ(PetscObjectComm(obj), PETSC_ERR_SUP, "Do not support borrowed arrays"); 2656*ea844a1aSMatthew Knepley ierr = PetscMalloc1(clSize, §ion->clInvPerm);CHKERRQ(ierr); 2657*ea844a1aSMatthew Knepley for (i = 0; i < clSize; ++i) section->clInvPerm[section->clPerm[i]] = i; 2658*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2659*ea844a1aSMatthew Knepley } 2660*ea844a1aSMatthew Knepley 2661*ea844a1aSMatthew Knepley /*@ 2662*ea844a1aSMatthew Knepley PetscSectionSetClosurePermutation - Get the dof permutation for the closure of each cell in the section, meaning clPerm[newIndex] = oldIndex. 2663*ea844a1aSMatthew Knepley 2664*ea844a1aSMatthew Knepley Not Collective 2665*ea844a1aSMatthew Knepley 2666*ea844a1aSMatthew Knepley Input Parameters: 2667*ea844a1aSMatthew Knepley + section - The PetscSection 2668*ea844a1aSMatthew Knepley . obj - A PetscObject which serves as the key for this index 2669*ea844a1aSMatthew Knepley - perm - Permutation of the cell dof closure 2670*ea844a1aSMatthew Knepley 2671*ea844a1aSMatthew Knepley Note: This strategy only works when all cells have the same size dof closure, and no closures are retrieved for 2672*ea844a1aSMatthew Knepley other points (like faces). 2673*ea844a1aSMatthew Knepley 2674*ea844a1aSMatthew Knepley Level: intermediate 2675*ea844a1aSMatthew Knepley 2676*ea844a1aSMatthew Knepley .seealso: PetscSectionGetClosurePermutation(), PetscSectionGetClosureIndex(), DMPlexCreateClosureIndex(), PetscCopyMode 2677*ea844a1aSMatthew Knepley @*/ 2678*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetClosurePermutation(PetscSection section, PetscObject obj, IS perm) 2679*ea844a1aSMatthew Knepley { 2680*ea844a1aSMatthew Knepley const PetscInt *clPerm = NULL; 2681*ea844a1aSMatthew Knepley PetscInt clSize = 0; 2682*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2683*ea844a1aSMatthew Knepley 2684*ea844a1aSMatthew Knepley PetscFunctionBegin; 2685*ea844a1aSMatthew Knepley if (perm) { 2686*ea844a1aSMatthew Knepley ierr = ISGetLocalSize(perm, &clSize);CHKERRQ(ierr); 2687*ea844a1aSMatthew Knepley ierr = ISGetIndices(perm, &clPerm);CHKERRQ(ierr); 2688*ea844a1aSMatthew Knepley } 2689*ea844a1aSMatthew Knepley ierr = PetscSectionSetClosurePermutation_Internal(section, obj, clSize, PETSC_COPY_VALUES, (PetscInt *) clPerm);CHKERRQ(ierr); 2690*ea844a1aSMatthew Knepley if (perm) {ierr = ISRestoreIndices(perm, &clPerm);CHKERRQ(ierr);} 2691*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2692*ea844a1aSMatthew Knepley } 2693*ea844a1aSMatthew Knepley 2694*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetClosurePermutation_Internal(PetscSection section, PetscObject obj, PetscInt *size, const PetscInt *perm[]) 2695*ea844a1aSMatthew Knepley { 2696*ea844a1aSMatthew Knepley PetscFunctionBegin; 2697*ea844a1aSMatthew Knepley if (section->clObj == obj) { 2698*ea844a1aSMatthew Knepley if (size) *size = section->clSize; 2699*ea844a1aSMatthew Knepley if (perm) *perm = section->clPerm; 2700*ea844a1aSMatthew Knepley } else { 2701*ea844a1aSMatthew Knepley if (size) *size = 0; 2702*ea844a1aSMatthew Knepley if (perm) *perm = NULL; 2703*ea844a1aSMatthew Knepley } 2704*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2705*ea844a1aSMatthew Knepley } 2706*ea844a1aSMatthew Knepley 2707*ea844a1aSMatthew Knepley /*@ 2708*ea844a1aSMatthew Knepley PetscSectionGetClosurePermutation - Get the dof permutation for the closure of each cell in the section, meaning clPerm[newIndex] = oldIndex. 2709*ea844a1aSMatthew Knepley 2710*ea844a1aSMatthew Knepley Not collective 2711*ea844a1aSMatthew Knepley 2712*ea844a1aSMatthew Knepley Input Parameters: 2713*ea844a1aSMatthew Knepley + section - The PetscSection 2714*ea844a1aSMatthew Knepley - obj - A PetscObject which serves as the key for this index 2715*ea844a1aSMatthew Knepley 2716*ea844a1aSMatthew Knepley Output Parameter: 2717*ea844a1aSMatthew Knepley . perm - The dof closure permutation 2718*ea844a1aSMatthew Knepley 2719*ea844a1aSMatthew Knepley Note: This strategy only works when all cells have the same size dof closure, and no closures are retrieved for 2720*ea844a1aSMatthew Knepley other points (like faces). 2721*ea844a1aSMatthew Knepley 2722*ea844a1aSMatthew Knepley The user must destroy the IS that is returned. 2723*ea844a1aSMatthew Knepley 2724*ea844a1aSMatthew Knepley Level: intermediate 2725*ea844a1aSMatthew Knepley 2726*ea844a1aSMatthew Knepley .seealso: PetscSectionSetClosurePermutation(), PetscSectionGetClosureInversePermutation(), PetscSectionGetClosureIndex(), PetscSectionSetClosureIndex(), DMPlexCreateClosureIndex() 2727*ea844a1aSMatthew Knepley @*/ 2728*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetClosurePermutation(PetscSection section, PetscObject obj, IS *perm) 2729*ea844a1aSMatthew Knepley { 2730*ea844a1aSMatthew Knepley const PetscInt *clPerm; 2731*ea844a1aSMatthew Knepley PetscInt clSize; 2732*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2733*ea844a1aSMatthew Knepley 2734*ea844a1aSMatthew Knepley PetscFunctionBegin; 2735*ea844a1aSMatthew Knepley ierr = PetscSectionGetClosurePermutation_Internal(section, obj, &clSize, &clPerm);CHKERRQ(ierr); 2736*ea844a1aSMatthew Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, clSize, clPerm, PETSC_USE_POINTER, perm);CHKERRQ(ierr); 2737*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2738*ea844a1aSMatthew Knepley } 2739*ea844a1aSMatthew Knepley 2740*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetClosureInversePermutation_Internal(PetscSection section, PetscObject obj, PetscInt *size, const PetscInt *perm[]) 2741*ea844a1aSMatthew Knepley { 2742*ea844a1aSMatthew Knepley PetscFunctionBegin; 2743*ea844a1aSMatthew Knepley if (section->clObj == obj) { 2744*ea844a1aSMatthew Knepley if (size) *size = section->clSize; 2745*ea844a1aSMatthew Knepley if (perm) *perm = section->clInvPerm; 2746*ea844a1aSMatthew Knepley } else { 2747*ea844a1aSMatthew Knepley if (size) *size = 0; 2748*ea844a1aSMatthew Knepley if (perm) *perm = NULL; 2749*ea844a1aSMatthew Knepley } 2750*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2751*ea844a1aSMatthew Knepley } 2752*ea844a1aSMatthew Knepley 2753*ea844a1aSMatthew Knepley /*@ 2754*ea844a1aSMatthew Knepley PetscSectionGetClosureInversePermutation - Get the inverse dof permutation for the closure of each cell in the section, meaning clPerm[oldIndex] = newIndex. 2755*ea844a1aSMatthew Knepley 2756*ea844a1aSMatthew Knepley Not collective 2757*ea844a1aSMatthew Knepley 2758*ea844a1aSMatthew Knepley Input Parameters: 2759*ea844a1aSMatthew Knepley + section - The PetscSection 2760*ea844a1aSMatthew Knepley - obj - A PetscObject which serves as the key for this index 2761*ea844a1aSMatthew Knepley 2762*ea844a1aSMatthew Knepley Output Parameters: 2763*ea844a1aSMatthew Knepley + size - The dof closure size 2764*ea844a1aSMatthew Knepley - perm - The dof closure permutation 2765*ea844a1aSMatthew Knepley 2766*ea844a1aSMatthew Knepley Note: This strategy only works when all cells have the same size dof closure, and no closures are retrieved for 2767*ea844a1aSMatthew Knepley other points (like faces). 2768*ea844a1aSMatthew Knepley 2769*ea844a1aSMatthew Knepley The user must destroy the IS that is returned. 2770*ea844a1aSMatthew Knepley 2771*ea844a1aSMatthew Knepley Level: intermediate 2772*ea844a1aSMatthew Knepley 2773*ea844a1aSMatthew Knepley .seealso: PetscSectionSetClosurePermutation(), PetscSectionGetClosureIndex(), PetscSectionSetClosureIndex(), DMPlexCreateClosureIndex() 2774*ea844a1aSMatthew Knepley @*/ 2775*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetClosureInversePermutation(PetscSection section, PetscObject obj, IS *perm) 2776*ea844a1aSMatthew Knepley { 2777*ea844a1aSMatthew Knepley const PetscInt *clPerm; 2778*ea844a1aSMatthew Knepley PetscInt clSize; 2779*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2780*ea844a1aSMatthew Knepley 2781*ea844a1aSMatthew Knepley PetscFunctionBegin; 2782*ea844a1aSMatthew Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, obj, &clSize, &clPerm);CHKERRQ(ierr); 2783*ea844a1aSMatthew Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, clSize, clPerm, PETSC_USE_POINTER, perm);CHKERRQ(ierr); 2784*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2785*ea844a1aSMatthew Knepley } 2786*ea844a1aSMatthew Knepley 2787*ea844a1aSMatthew Knepley /*@ 2788*ea844a1aSMatthew Knepley PetscSectionGetField - Get the subsection associated with a single field 2789*ea844a1aSMatthew Knepley 2790*ea844a1aSMatthew Knepley Input Parameters: 2791*ea844a1aSMatthew Knepley + s - The PetscSection 2792*ea844a1aSMatthew Knepley - field - The field number 2793*ea844a1aSMatthew Knepley 2794*ea844a1aSMatthew Knepley Output Parameter: 2795*ea844a1aSMatthew Knepley . subs - The subsection for the given field 2796*ea844a1aSMatthew Knepley 2797*ea844a1aSMatthew Knepley Level: intermediate 2798*ea844a1aSMatthew Knepley 2799*ea844a1aSMatthew Knepley .seealso: PetscSectionSetNumFields() 2800*ea844a1aSMatthew Knepley @*/ 2801*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetField(PetscSection s, PetscInt field, PetscSection *subs) 2802*ea844a1aSMatthew Knepley { 2803*ea844a1aSMatthew Knepley PetscFunctionBegin; 2804*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s,PETSC_SECTION_CLASSID,1); 2805*ea844a1aSMatthew Knepley PetscValidPointer(subs,3); 2806*ea844a1aSMatthew Knepley if ((field < 0) || (field >= s->numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %D should be in [%D, %D)", field, 0, s->numFields); 2807*ea844a1aSMatthew Knepley *subs = s->field[field]; 2808*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2809*ea844a1aSMatthew Knepley } 2810*ea844a1aSMatthew Knepley 2811*ea844a1aSMatthew Knepley PetscClassId PETSC_SECTION_SYM_CLASSID; 2812*ea844a1aSMatthew Knepley PetscFunctionList PetscSectionSymList = NULL; 2813*ea844a1aSMatthew Knepley 2814*ea844a1aSMatthew Knepley /*@ 2815*ea844a1aSMatthew Knepley PetscSectionSymCreate - Creates an empty PetscSectionSym object. 2816*ea844a1aSMatthew Knepley 2817*ea844a1aSMatthew Knepley Collective 2818*ea844a1aSMatthew Knepley 2819*ea844a1aSMatthew Knepley Input Parameter: 2820*ea844a1aSMatthew Knepley . comm - the MPI communicator 2821*ea844a1aSMatthew Knepley 2822*ea844a1aSMatthew Knepley Output Parameter: 2823*ea844a1aSMatthew Knepley . sym - pointer to the new set of symmetries 2824*ea844a1aSMatthew Knepley 2825*ea844a1aSMatthew Knepley Level: developer 2826*ea844a1aSMatthew Knepley 2827*ea844a1aSMatthew Knepley .seealso: PetscSectionSym, PetscSectionSymDestroy() 2828*ea844a1aSMatthew Knepley @*/ 2829*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymCreate(MPI_Comm comm, PetscSectionSym *sym) 2830*ea844a1aSMatthew Knepley { 2831*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2832*ea844a1aSMatthew Knepley 2833*ea844a1aSMatthew Knepley PetscFunctionBegin; 2834*ea844a1aSMatthew Knepley PetscValidPointer(sym,2); 2835*ea844a1aSMatthew Knepley ierr = ISInitializePackage();CHKERRQ(ierr); 2836*ea844a1aSMatthew Knepley ierr = PetscHeaderCreate(*sym,PETSC_SECTION_SYM_CLASSID,"PetscSectionSym","Section Symmetry","IS",comm,PetscSectionSymDestroy,PetscSectionSymView);CHKERRQ(ierr); 2837*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2838*ea844a1aSMatthew Knepley } 2839*ea844a1aSMatthew Knepley 2840*ea844a1aSMatthew Knepley /*@C 2841*ea844a1aSMatthew Knepley PetscSectionSymSetType - Builds a PetscSection symmetry, for a particular implementation. 2842*ea844a1aSMatthew Knepley 2843*ea844a1aSMatthew Knepley Collective on PetscSectionSym 2844*ea844a1aSMatthew Knepley 2845*ea844a1aSMatthew Knepley Input Parameters: 2846*ea844a1aSMatthew Knepley + sym - The section symmetry object 2847*ea844a1aSMatthew Knepley - method - The name of the section symmetry type 2848*ea844a1aSMatthew Knepley 2849*ea844a1aSMatthew Knepley Level: developer 2850*ea844a1aSMatthew Knepley 2851*ea844a1aSMatthew Knepley .seealso: PetscSectionSymGetType(), PetscSectionSymCreate() 2852*ea844a1aSMatthew Knepley @*/ 2853*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymSetType(PetscSectionSym sym, PetscSectionSymType method) 2854*ea844a1aSMatthew Knepley { 2855*ea844a1aSMatthew Knepley PetscErrorCode (*r)(PetscSectionSym); 2856*ea844a1aSMatthew Knepley PetscBool match; 2857*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2858*ea844a1aSMatthew Knepley 2859*ea844a1aSMatthew Knepley PetscFunctionBegin; 2860*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID,1); 2861*ea844a1aSMatthew Knepley ierr = PetscObjectTypeCompare((PetscObject) sym, method, &match);CHKERRQ(ierr); 2862*ea844a1aSMatthew Knepley if (match) PetscFunctionReturn(0); 2863*ea844a1aSMatthew Knepley 2864*ea844a1aSMatthew Knepley ierr = PetscFunctionListFind(PetscSectionSymList,method,&r);CHKERRQ(ierr); 2865*ea844a1aSMatthew Knepley if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSectionSym type: %s", method); 2866*ea844a1aSMatthew Knepley if (sym->ops->destroy) { 2867*ea844a1aSMatthew Knepley ierr = (*sym->ops->destroy)(sym);CHKERRQ(ierr); 2868*ea844a1aSMatthew Knepley sym->ops->destroy = NULL; 2869*ea844a1aSMatthew Knepley } 2870*ea844a1aSMatthew Knepley ierr = (*r)(sym);CHKERRQ(ierr); 2871*ea844a1aSMatthew Knepley ierr = PetscObjectChangeTypeName((PetscObject)sym,method);CHKERRQ(ierr); 2872*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2873*ea844a1aSMatthew Knepley } 2874*ea844a1aSMatthew Knepley 2875*ea844a1aSMatthew Knepley 2876*ea844a1aSMatthew Knepley /*@C 2877*ea844a1aSMatthew Knepley PetscSectionSymGetType - Gets the section symmetry type name (as a string) from the PetscSectionSym. 2878*ea844a1aSMatthew Knepley 2879*ea844a1aSMatthew Knepley Not Collective 2880*ea844a1aSMatthew Knepley 2881*ea844a1aSMatthew Knepley Input Parameter: 2882*ea844a1aSMatthew Knepley . sym - The section symmetry 2883*ea844a1aSMatthew Knepley 2884*ea844a1aSMatthew Knepley Output Parameter: 2885*ea844a1aSMatthew Knepley . type - The index set type name 2886*ea844a1aSMatthew Knepley 2887*ea844a1aSMatthew Knepley Level: developer 2888*ea844a1aSMatthew Knepley 2889*ea844a1aSMatthew Knepley .seealso: PetscSectionSymSetType(), PetscSectionSymCreate() 2890*ea844a1aSMatthew Knepley @*/ 2891*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymGetType(PetscSectionSym sym, PetscSectionSymType *type) 2892*ea844a1aSMatthew Knepley { 2893*ea844a1aSMatthew Knepley PetscFunctionBegin; 2894*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID,1); 2895*ea844a1aSMatthew Knepley PetscValidCharPointer(type,2); 2896*ea844a1aSMatthew Knepley *type = ((PetscObject)sym)->type_name; 2897*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2898*ea844a1aSMatthew Knepley } 2899*ea844a1aSMatthew Knepley 2900*ea844a1aSMatthew Knepley /*@C 2901*ea844a1aSMatthew Knepley PetscSectionSymRegister - Adds a new section symmetry implementation 2902*ea844a1aSMatthew Knepley 2903*ea844a1aSMatthew Knepley Not Collective 2904*ea844a1aSMatthew Knepley 2905*ea844a1aSMatthew Knepley Input Parameters: 2906*ea844a1aSMatthew Knepley + name - The name of a new user-defined creation routine 2907*ea844a1aSMatthew Knepley - create_func - The creation routine itself 2908*ea844a1aSMatthew Knepley 2909*ea844a1aSMatthew Knepley Notes: 2910*ea844a1aSMatthew Knepley PetscSectionSymRegister() may be called multiple times to add several user-defined vectors 2911*ea844a1aSMatthew Knepley 2912*ea844a1aSMatthew Knepley Level: developer 2913*ea844a1aSMatthew Knepley 2914*ea844a1aSMatthew Knepley .seealso: PetscSectionSymCreate(), PetscSectionSymSetType() 2915*ea844a1aSMatthew Knepley @*/ 2916*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymRegister(const char sname[], PetscErrorCode (*function)(PetscSectionSym)) 2917*ea844a1aSMatthew Knepley { 2918*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2919*ea844a1aSMatthew Knepley 2920*ea844a1aSMatthew Knepley PetscFunctionBegin; 2921*ea844a1aSMatthew Knepley ierr = ISInitializePackage();CHKERRQ(ierr); 2922*ea844a1aSMatthew Knepley ierr = PetscFunctionListAdd(&PetscSectionSymList,sname,function);CHKERRQ(ierr); 2923*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2924*ea844a1aSMatthew Knepley } 2925*ea844a1aSMatthew Knepley 2926*ea844a1aSMatthew Knepley /*@ 2927*ea844a1aSMatthew Knepley PetscSectionSymDestroy - Destroys a section symmetry. 2928*ea844a1aSMatthew Knepley 2929*ea844a1aSMatthew Knepley Collective on PetscSectionSym 2930*ea844a1aSMatthew Knepley 2931*ea844a1aSMatthew Knepley Input Parameters: 2932*ea844a1aSMatthew Knepley . sym - the section symmetry 2933*ea844a1aSMatthew Knepley 2934*ea844a1aSMatthew Knepley Level: developer 2935*ea844a1aSMatthew Knepley 2936*ea844a1aSMatthew Knepley .seealso: PetscSectionSymCreate(), PetscSectionSymDestroy() 2937*ea844a1aSMatthew Knepley @*/ 2938*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymDestroy(PetscSectionSym *sym) 2939*ea844a1aSMatthew Knepley { 2940*ea844a1aSMatthew Knepley SymWorkLink link,next; 2941*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2942*ea844a1aSMatthew Knepley 2943*ea844a1aSMatthew Knepley PetscFunctionBegin; 2944*ea844a1aSMatthew Knepley if (!*sym) PetscFunctionReturn(0); 2945*ea844a1aSMatthew Knepley PetscValidHeaderSpecific((*sym),PETSC_SECTION_SYM_CLASSID,1); 2946*ea844a1aSMatthew Knepley if (--((PetscObject)(*sym))->refct > 0) {*sym = 0; PetscFunctionReturn(0);} 2947*ea844a1aSMatthew Knepley if ((*sym)->ops->destroy) { 2948*ea844a1aSMatthew Knepley ierr = (*(*sym)->ops->destroy)(*sym);CHKERRQ(ierr); 2949*ea844a1aSMatthew Knepley } 2950*ea844a1aSMatthew Knepley if ((*sym)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 2951*ea844a1aSMatthew Knepley for (link=(*sym)->workin; link; link=next) { 2952*ea844a1aSMatthew Knepley next = link->next; 2953*ea844a1aSMatthew Knepley ierr = PetscFree2(*(PetscInt***)&link->perms,*(PetscScalar***)&link->rots);CHKERRQ(ierr); 2954*ea844a1aSMatthew Knepley ierr = PetscFree(link);CHKERRQ(ierr); 2955*ea844a1aSMatthew Knepley } 2956*ea844a1aSMatthew Knepley (*sym)->workin = NULL; 2957*ea844a1aSMatthew Knepley ierr = PetscHeaderDestroy(sym);CHKERRQ(ierr); 2958*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2959*ea844a1aSMatthew Knepley } 2960*ea844a1aSMatthew Knepley 2961*ea844a1aSMatthew Knepley /*@C 2962*ea844a1aSMatthew Knepley PetscSectionSymView - Displays a section symmetry 2963*ea844a1aSMatthew Knepley 2964*ea844a1aSMatthew Knepley Collective on PetscSectionSym 2965*ea844a1aSMatthew Knepley 2966*ea844a1aSMatthew Knepley Input Parameters: 2967*ea844a1aSMatthew Knepley + sym - the index set 2968*ea844a1aSMatthew Knepley - viewer - viewer used to display the set, for example PETSC_VIEWER_STDOUT_SELF. 2969*ea844a1aSMatthew Knepley 2970*ea844a1aSMatthew Knepley Level: developer 2971*ea844a1aSMatthew Knepley 2972*ea844a1aSMatthew Knepley .seealso: PetscViewerASCIIOpen() 2973*ea844a1aSMatthew Knepley @*/ 2974*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSymView(PetscSectionSym sym,PetscViewer viewer) 2975*ea844a1aSMatthew Knepley { 2976*ea844a1aSMatthew Knepley PetscErrorCode ierr; 2977*ea844a1aSMatthew Knepley 2978*ea844a1aSMatthew Knepley PetscFunctionBegin; 2979*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 2980*ea844a1aSMatthew Knepley if (!viewer) { 2981*ea844a1aSMatthew Knepley ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sym),&viewer);CHKERRQ(ierr); 2982*ea844a1aSMatthew Knepley } 2983*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 2984*ea844a1aSMatthew Knepley PetscCheckSameComm(sym,1,viewer,2); 2985*ea844a1aSMatthew Knepley ierr = PetscObjectPrintClassNamePrefixType((PetscObject)sym,viewer);CHKERRQ(ierr); 2986*ea844a1aSMatthew Knepley if (sym->ops->view) { 2987*ea844a1aSMatthew Knepley ierr = (*sym->ops->view)(sym,viewer);CHKERRQ(ierr); 2988*ea844a1aSMatthew Knepley } 2989*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 2990*ea844a1aSMatthew Knepley } 2991*ea844a1aSMatthew Knepley 2992*ea844a1aSMatthew Knepley /*@ 2993*ea844a1aSMatthew Knepley PetscSectionSetSym - Set the symmetries for the data referred to by the section 2994*ea844a1aSMatthew Knepley 2995*ea844a1aSMatthew Knepley Collective on PetscSection 2996*ea844a1aSMatthew Knepley 2997*ea844a1aSMatthew Knepley Input Parameters: 2998*ea844a1aSMatthew Knepley + section - the section describing data layout 2999*ea844a1aSMatthew Knepley - sym - the symmetry describing the affect of orientation on the access of the data 3000*ea844a1aSMatthew Knepley 3001*ea844a1aSMatthew Knepley Level: developer 3002*ea844a1aSMatthew Knepley 3003*ea844a1aSMatthew Knepley .seealso: PetscSectionGetSym(), PetscSectionSymCreate() 3004*ea844a1aSMatthew Knepley @*/ 3005*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetSym(PetscSection section, PetscSectionSym sym) 3006*ea844a1aSMatthew Knepley { 3007*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3008*ea844a1aSMatthew Knepley 3009*ea844a1aSMatthew Knepley PetscFunctionBegin; 3010*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3011*ea844a1aSMatthew Knepley ierr = PetscSectionSymDestroy(&(section->sym));CHKERRQ(ierr); 3012*ea844a1aSMatthew Knepley if (sym) { 3013*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,2); 3014*ea844a1aSMatthew Knepley PetscCheckSameComm(section,1,sym,2); 3015*ea844a1aSMatthew Knepley ierr = PetscObjectReference((PetscObject) sym);CHKERRQ(ierr); 3016*ea844a1aSMatthew Knepley } 3017*ea844a1aSMatthew Knepley section->sym = sym; 3018*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3019*ea844a1aSMatthew Knepley } 3020*ea844a1aSMatthew Knepley 3021*ea844a1aSMatthew Knepley /*@ 3022*ea844a1aSMatthew Knepley PetscSectionGetSym - Get the symmetries for the data referred to by the section 3023*ea844a1aSMatthew Knepley 3024*ea844a1aSMatthew Knepley Not collective 3025*ea844a1aSMatthew Knepley 3026*ea844a1aSMatthew Knepley Input Parameters: 3027*ea844a1aSMatthew Knepley . section - the section describing data layout 3028*ea844a1aSMatthew Knepley 3029*ea844a1aSMatthew Knepley Output Parameters: 3030*ea844a1aSMatthew Knepley . sym - the symmetry describing the affect of orientation on the access of the data 3031*ea844a1aSMatthew Knepley 3032*ea844a1aSMatthew Knepley Level: developer 3033*ea844a1aSMatthew Knepley 3034*ea844a1aSMatthew Knepley .seealso: PetscSectionSetSym(), PetscSectionSymCreate() 3035*ea844a1aSMatthew Knepley @*/ 3036*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetSym(PetscSection section, PetscSectionSym *sym) 3037*ea844a1aSMatthew Knepley { 3038*ea844a1aSMatthew Knepley PetscFunctionBegin; 3039*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3040*ea844a1aSMatthew Knepley *sym = section->sym; 3041*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3042*ea844a1aSMatthew Knepley } 3043*ea844a1aSMatthew Knepley 3044*ea844a1aSMatthew Knepley /*@ 3045*ea844a1aSMatthew Knepley PetscSectionSetFieldSym - Set the symmetries for the data referred to by a field of the section 3046*ea844a1aSMatthew Knepley 3047*ea844a1aSMatthew Knepley Collective on PetscSection 3048*ea844a1aSMatthew Knepley 3049*ea844a1aSMatthew Knepley Input Parameters: 3050*ea844a1aSMatthew Knepley + section - the section describing data layout 3051*ea844a1aSMatthew Knepley . field - the field number 3052*ea844a1aSMatthew Knepley - sym - the symmetry describing the affect of orientation on the access of the data 3053*ea844a1aSMatthew Knepley 3054*ea844a1aSMatthew Knepley Level: developer 3055*ea844a1aSMatthew Knepley 3056*ea844a1aSMatthew Knepley .seealso: PetscSectionGetFieldSym(), PetscSectionSymCreate() 3057*ea844a1aSMatthew Knepley @*/ 3058*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetFieldSym(PetscSection section, PetscInt field, PetscSectionSym sym) 3059*ea844a1aSMatthew Knepley { 3060*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3061*ea844a1aSMatthew Knepley 3062*ea844a1aSMatthew Knepley PetscFunctionBegin; 3063*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3064*ea844a1aSMatthew Knepley if (field < 0 || field >= section->numFields) SETERRQ2(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number %D (not in [0,%D)", field, section->numFields); 3065*ea844a1aSMatthew Knepley ierr = PetscSectionSetSym(section->field[field],sym);CHKERRQ(ierr); 3066*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3067*ea844a1aSMatthew Knepley } 3068*ea844a1aSMatthew Knepley 3069*ea844a1aSMatthew Knepley /*@ 3070*ea844a1aSMatthew Knepley PetscSectionGetFieldSym - Get the symmetries for the data referred to by a field of the section 3071*ea844a1aSMatthew Knepley 3072*ea844a1aSMatthew Knepley Collective on PetscSection 3073*ea844a1aSMatthew Knepley 3074*ea844a1aSMatthew Knepley Input Parameters: 3075*ea844a1aSMatthew Knepley + section - the section describing data layout 3076*ea844a1aSMatthew Knepley - field - the field number 3077*ea844a1aSMatthew Knepley 3078*ea844a1aSMatthew Knepley Output Parameters: 3079*ea844a1aSMatthew Knepley . sym - the symmetry describing the affect of orientation on the access of the data 3080*ea844a1aSMatthew Knepley 3081*ea844a1aSMatthew Knepley Level: developer 3082*ea844a1aSMatthew Knepley 3083*ea844a1aSMatthew Knepley .seealso: PetscSectionSetFieldSym(), PetscSectionSymCreate() 3084*ea844a1aSMatthew Knepley @*/ 3085*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldSym(PetscSection section, PetscInt field, PetscSectionSym *sym) 3086*ea844a1aSMatthew Knepley { 3087*ea844a1aSMatthew Knepley PetscFunctionBegin; 3088*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3089*ea844a1aSMatthew Knepley if (field < 0 || field >= section->numFields) SETERRQ2(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number %D (not in [0,%D)", field, section->numFields); 3090*ea844a1aSMatthew Knepley *sym = section->field[field]->sym; 3091*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3092*ea844a1aSMatthew Knepley } 3093*ea844a1aSMatthew Knepley 3094*ea844a1aSMatthew Knepley /*@C 3095*ea844a1aSMatthew Knepley PetscSectionGetPointSyms - Get the symmetries for a set of points in a PetscSection under specific orientations. 3096*ea844a1aSMatthew Knepley 3097*ea844a1aSMatthew Knepley Not collective 3098*ea844a1aSMatthew Knepley 3099*ea844a1aSMatthew Knepley Input Parameters: 3100*ea844a1aSMatthew Knepley + section - the section 3101*ea844a1aSMatthew Knepley . numPoints - the number of points 3102*ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an 3103*ea844a1aSMatthew Knepley arbitrary integer: its interpretation is up to sym. Orientations are used by DM: for their interpretation in that 3104*ea844a1aSMatthew Knepley context, see DMPlexGetConeOrientation()). 3105*ea844a1aSMatthew Knepley 3106*ea844a1aSMatthew Knepley Output Parameter: 3107*ea844a1aSMatthew Knepley + perms - The permutations for the given orientations (or NULL if there is no symmetry or the permutation is the identity). 3108*ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations (or NULL if there is no symmetry or the rotations are all 3109*ea844a1aSMatthew Knepley identity). 3110*ea844a1aSMatthew Knepley 3111*ea844a1aSMatthew Knepley Example of usage, gathering dofs into a local array (lArray) from a section array (sArray): 3112*ea844a1aSMatthew Knepley .vb 3113*ea844a1aSMatthew Knepley const PetscInt **perms; 3114*ea844a1aSMatthew Knepley const PetscScalar **rots; 3115*ea844a1aSMatthew Knepley PetscInt lOffset; 3116*ea844a1aSMatthew Knepley 3117*ea844a1aSMatthew Knepley PetscSectionGetPointSyms(section,numPoints,points,&perms,&rots); 3118*ea844a1aSMatthew Knepley for (i = 0, lOffset = 0; i < numPoints; i++) { 3119*ea844a1aSMatthew Knepley PetscInt point = points[2*i], dof, sOffset; 3120*ea844a1aSMatthew Knepley const PetscInt *perm = perms ? perms[i] : NULL; 3121*ea844a1aSMatthew Knepley const PetscScalar *rot = rots ? rots[i] : NULL; 3122*ea844a1aSMatthew Knepley 3123*ea844a1aSMatthew Knepley PetscSectionGetDof(section,point,&dof); 3124*ea844a1aSMatthew Knepley PetscSectionGetOffset(section,point,&sOffset); 3125*ea844a1aSMatthew Knepley 3126*ea844a1aSMatthew Knepley if (perm) {for (j = 0; j < dof; j++) {lArray[lOffset + perm[j]] = sArray[sOffset + j];}} 3127*ea844a1aSMatthew Knepley else {for (j = 0; j < dof; j++) {lArray[lOffset + j ] = sArray[sOffset + j];}} 3128*ea844a1aSMatthew Knepley if (rot) {for (j = 0; j < dof; j++) {lArray[lOffset + j ] *= rot[j]; }} 3129*ea844a1aSMatthew Knepley lOffset += dof; 3130*ea844a1aSMatthew Knepley } 3131*ea844a1aSMatthew Knepley PetscSectionRestorePointSyms(section,numPoints,points,&perms,&rots); 3132*ea844a1aSMatthew Knepley .ve 3133*ea844a1aSMatthew Knepley 3134*ea844a1aSMatthew Knepley Example of usage, adding dofs into a section array (sArray) from a local array (lArray): 3135*ea844a1aSMatthew Knepley .vb 3136*ea844a1aSMatthew Knepley const PetscInt **perms; 3137*ea844a1aSMatthew Knepley const PetscScalar **rots; 3138*ea844a1aSMatthew Knepley PetscInt lOffset; 3139*ea844a1aSMatthew Knepley 3140*ea844a1aSMatthew Knepley PetscSectionGetPointSyms(section,numPoints,points,&perms,&rots); 3141*ea844a1aSMatthew Knepley for (i = 0, lOffset = 0; i < numPoints; i++) { 3142*ea844a1aSMatthew Knepley PetscInt point = points[2*i], dof, sOffset; 3143*ea844a1aSMatthew Knepley const PetscInt *perm = perms ? perms[i] : NULL; 3144*ea844a1aSMatthew Knepley const PetscScalar *rot = rots ? rots[i] : NULL; 3145*ea844a1aSMatthew Knepley 3146*ea844a1aSMatthew Knepley PetscSectionGetDof(section,point,&dof); 3147*ea844a1aSMatthew Knepley PetscSectionGetOffset(section,point,&sOff); 3148*ea844a1aSMatthew Knepley 3149*ea844a1aSMatthew Knepley if (perm) {for (j = 0; j < dof; j++) {sArray[sOffset + j] += lArray[lOffset + perm[j]] * (rot ? PetscConj(rot[perm[j]]) : 1.);}} 3150*ea844a1aSMatthew Knepley else {for (j = 0; j < dof; j++) {sArray[sOffset + j] += lArray[lOffset + j ] * (rot ? PetscConj(rot[ j ]) : 1.);}} 3151*ea844a1aSMatthew Knepley offset += dof; 3152*ea844a1aSMatthew Knepley } 3153*ea844a1aSMatthew Knepley PetscSectionRestorePointSyms(section,numPoints,points,&perms,&rots); 3154*ea844a1aSMatthew Knepley .ve 3155*ea844a1aSMatthew Knepley 3156*ea844a1aSMatthew Knepley Level: developer 3157*ea844a1aSMatthew Knepley 3158*ea844a1aSMatthew Knepley .seealso: PetscSectionRestorePointSyms(), PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym() 3159*ea844a1aSMatthew Knepley @*/ 3160*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetPointSyms(PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) 3161*ea844a1aSMatthew Knepley { 3162*ea844a1aSMatthew Knepley PetscSectionSym sym; 3163*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3164*ea844a1aSMatthew Knepley 3165*ea844a1aSMatthew Knepley PetscFunctionBegin; 3166*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3167*ea844a1aSMatthew Knepley if (numPoints) PetscValidIntPointer(points,3); 3168*ea844a1aSMatthew Knepley if (perms) *perms = NULL; 3169*ea844a1aSMatthew Knepley if (rots) *rots = NULL; 3170*ea844a1aSMatthew Knepley sym = section->sym; 3171*ea844a1aSMatthew Knepley if (sym && (perms || rots)) { 3172*ea844a1aSMatthew Knepley SymWorkLink link; 3173*ea844a1aSMatthew Knepley 3174*ea844a1aSMatthew Knepley if (sym->workin) { 3175*ea844a1aSMatthew Knepley link = sym->workin; 3176*ea844a1aSMatthew Knepley sym->workin = sym->workin->next; 3177*ea844a1aSMatthew Knepley } else { 3178*ea844a1aSMatthew Knepley ierr = PetscNewLog(sym,&link);CHKERRQ(ierr); 3179*ea844a1aSMatthew Knepley } 3180*ea844a1aSMatthew Knepley if (numPoints > link->numPoints) { 3181*ea844a1aSMatthew Knepley ierr = PetscFree2(*(PetscInt***)&link->perms,*(PetscInt***)&link->rots);CHKERRQ(ierr); 3182*ea844a1aSMatthew Knepley ierr = PetscMalloc2(numPoints,(PetscInt***)&link->perms,numPoints,(PetscScalar***)&link->rots);CHKERRQ(ierr); 3183*ea844a1aSMatthew Knepley link->numPoints = numPoints; 3184*ea844a1aSMatthew Knepley } 3185*ea844a1aSMatthew Knepley link->next = sym->workout; 3186*ea844a1aSMatthew Knepley sym->workout = link; 3187*ea844a1aSMatthew Knepley ierr = PetscArrayzero((PetscInt**)link->perms,numPoints);CHKERRQ(ierr); 3188*ea844a1aSMatthew Knepley ierr = PetscArrayzero((PetscInt**)link->rots,numPoints);CHKERRQ(ierr); 3189*ea844a1aSMatthew Knepley ierr = (*sym->ops->getpoints) (sym, section, numPoints, points, link->perms, link->rots);CHKERRQ(ierr); 3190*ea844a1aSMatthew Knepley if (perms) *perms = link->perms; 3191*ea844a1aSMatthew Knepley if (rots) *rots = link->rots; 3192*ea844a1aSMatthew Knepley } 3193*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3194*ea844a1aSMatthew Knepley } 3195*ea844a1aSMatthew Knepley 3196*ea844a1aSMatthew Knepley /*@C 3197*ea844a1aSMatthew Knepley PetscSectionRestorePointSyms - Restore the symmetries returned by PetscSectionGetPointSyms() 3198*ea844a1aSMatthew Knepley 3199*ea844a1aSMatthew Knepley Not collective 3200*ea844a1aSMatthew Knepley 3201*ea844a1aSMatthew Knepley Input Parameters: 3202*ea844a1aSMatthew Knepley + section - the section 3203*ea844a1aSMatthew Knepley . numPoints - the number of points 3204*ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an 3205*ea844a1aSMatthew Knepley arbitrary integer: its interpretation is up to sym. Orientations are used by DM: for their interpretation in that 3206*ea844a1aSMatthew Knepley context, see DMPlexGetConeOrientation()). 3207*ea844a1aSMatthew Knepley 3208*ea844a1aSMatthew Knepley Output Parameter: 3209*ea844a1aSMatthew Knepley + perms - The permutations for the given orientations: set to NULL at conclusion 3210*ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations: set to NULL at conclusion 3211*ea844a1aSMatthew Knepley 3212*ea844a1aSMatthew Knepley Level: developer 3213*ea844a1aSMatthew Knepley 3214*ea844a1aSMatthew Knepley .seealso: PetscSectionGetPointSyms(), PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym() 3215*ea844a1aSMatthew Knepley @*/ 3216*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionRestorePointSyms(PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) 3217*ea844a1aSMatthew Knepley { 3218*ea844a1aSMatthew Knepley PetscSectionSym sym; 3219*ea844a1aSMatthew Knepley 3220*ea844a1aSMatthew Knepley PetscFunctionBegin; 3221*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3222*ea844a1aSMatthew Knepley sym = section->sym; 3223*ea844a1aSMatthew Knepley if (sym && (perms || rots)) { 3224*ea844a1aSMatthew Knepley SymWorkLink *p,link; 3225*ea844a1aSMatthew Knepley 3226*ea844a1aSMatthew Knepley for (p=&sym->workout; (link=*p); p=&link->next) { 3227*ea844a1aSMatthew Knepley if ((perms && link->perms == *perms) || (rots && link->rots == *rots)) { 3228*ea844a1aSMatthew Knepley *p = link->next; 3229*ea844a1aSMatthew Knepley link->next = sym->workin; 3230*ea844a1aSMatthew Knepley sym->workin = link; 3231*ea844a1aSMatthew Knepley if (perms) *perms = NULL; 3232*ea844a1aSMatthew Knepley if (rots) *rots = NULL; 3233*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3234*ea844a1aSMatthew Knepley } 3235*ea844a1aSMatthew Knepley } 3236*ea844a1aSMatthew Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 3237*ea844a1aSMatthew Knepley } 3238*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3239*ea844a1aSMatthew Knepley } 3240*ea844a1aSMatthew Knepley 3241*ea844a1aSMatthew Knepley /*@C 3242*ea844a1aSMatthew Knepley PetscSectionGetFieldPointSyms - Get the symmetries for a set of points in a field of a PetscSection under specific orientations. 3243*ea844a1aSMatthew Knepley 3244*ea844a1aSMatthew Knepley Not collective 3245*ea844a1aSMatthew Knepley 3246*ea844a1aSMatthew Knepley Input Parameters: 3247*ea844a1aSMatthew Knepley + section - the section 3248*ea844a1aSMatthew Knepley . field - the field of the section 3249*ea844a1aSMatthew Knepley . numPoints - the number of points 3250*ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an 3251*ea844a1aSMatthew Knepley arbitrary integer: its interpretation is up to sym. Orientations are used by DM: for their interpretation in that 3252*ea844a1aSMatthew Knepley context, see DMPlexGetConeOrientation()). 3253*ea844a1aSMatthew Knepley 3254*ea844a1aSMatthew Knepley Output Parameter: 3255*ea844a1aSMatthew Knepley + perms - The permutations for the given orientations (or NULL if there is no symmetry or the permutation is the identity). 3256*ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations (or NULL if there is no symmetry or the rotations are all 3257*ea844a1aSMatthew Knepley identity). 3258*ea844a1aSMatthew Knepley 3259*ea844a1aSMatthew Knepley Level: developer 3260*ea844a1aSMatthew Knepley 3261*ea844a1aSMatthew Knepley .seealso: PetscSectionGetPointSyms(), PetscSectionRestoreFieldPointSyms() 3262*ea844a1aSMatthew Knepley @*/ 3263*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetFieldPointSyms(PetscSection section, PetscInt field, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) 3264*ea844a1aSMatthew Knepley { 3265*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3266*ea844a1aSMatthew Knepley 3267*ea844a1aSMatthew Knepley PetscFunctionBegin; 3268*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3269*ea844a1aSMatthew Knepley if (field > section->numFields) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"field %D greater than number of fields (%D) in section",field,section->numFields); 3270*ea844a1aSMatthew Knepley ierr = PetscSectionGetPointSyms(section->field[field],numPoints,points,perms,rots);CHKERRQ(ierr); 3271*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3272*ea844a1aSMatthew Knepley } 3273*ea844a1aSMatthew Knepley 3274*ea844a1aSMatthew Knepley /*@C 3275*ea844a1aSMatthew Knepley PetscSectionRestoreFieldPointSyms - Restore the symmetries returned by PetscSectionGetFieldPointSyms() 3276*ea844a1aSMatthew Knepley 3277*ea844a1aSMatthew Knepley Not collective 3278*ea844a1aSMatthew Knepley 3279*ea844a1aSMatthew Knepley Input Parameters: 3280*ea844a1aSMatthew Knepley + section - the section 3281*ea844a1aSMatthew Knepley . field - the field number 3282*ea844a1aSMatthew Knepley . numPoints - the number of points 3283*ea844a1aSMatthew Knepley - points - an array of size 2 * numPoints, containing a list of (point, orientation) pairs. (An orientation is an 3284*ea844a1aSMatthew Knepley arbitrary integer: its interpretation is up to sym. Orientations are used by DM: for their interpretation in that 3285*ea844a1aSMatthew Knepley context, see DMPlexGetConeOrientation()). 3286*ea844a1aSMatthew Knepley 3287*ea844a1aSMatthew Knepley Output Parameter: 3288*ea844a1aSMatthew Knepley + perms - The permutations for the given orientations: set to NULL at conclusion 3289*ea844a1aSMatthew Knepley - rots - The field rotations symmetries for the given orientations: set to NULL at conclusion 3290*ea844a1aSMatthew Knepley 3291*ea844a1aSMatthew Knepley Level: developer 3292*ea844a1aSMatthew Knepley 3293*ea844a1aSMatthew Knepley .seealso: PetscSectionRestorePointSyms(), petscSectionGetFieldPointSyms(), PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym() 3294*ea844a1aSMatthew Knepley @*/ 3295*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionRestoreFieldPointSyms(PetscSection section, PetscInt field, PetscInt numPoints, const PetscInt *points, const PetscInt ***perms, const PetscScalar ***rots) 3296*ea844a1aSMatthew Knepley { 3297*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3298*ea844a1aSMatthew Knepley 3299*ea844a1aSMatthew Knepley PetscFunctionBegin; 3300*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,1); 3301*ea844a1aSMatthew Knepley if (field > section->numFields) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"field %D greater than number of fields (%D) in section",field,section->numFields); 3302*ea844a1aSMatthew Knepley ierr = PetscSectionRestorePointSyms(section->field[field],numPoints,points,perms,rots);CHKERRQ(ierr); 3303*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3304*ea844a1aSMatthew Knepley } 3305*ea844a1aSMatthew Knepley 3306*ea844a1aSMatthew Knepley /*@ 3307*ea844a1aSMatthew Knepley PetscSectionGetUseFieldOffsets - Get the flag to use field offsets directly in a global section, rather than just the point offset 3308*ea844a1aSMatthew Knepley 3309*ea844a1aSMatthew Knepley Not collective 3310*ea844a1aSMatthew Knepley 3311*ea844a1aSMatthew Knepley Input Parameter: 3312*ea844a1aSMatthew Knepley . s - the global PetscSection 3313*ea844a1aSMatthew Knepley 3314*ea844a1aSMatthew Knepley Output Parameters: 3315*ea844a1aSMatthew Knepley . flg - the flag 3316*ea844a1aSMatthew Knepley 3317*ea844a1aSMatthew Knepley Level: developer 3318*ea844a1aSMatthew Knepley 3319*ea844a1aSMatthew Knepley .seealso: PetscSectionSetChart(), PetscSectionCreate() 3320*ea844a1aSMatthew Knepley @*/ 3321*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionGetUseFieldOffsets(PetscSection s, PetscBool *flg) 3322*ea844a1aSMatthew Knepley { 3323*ea844a1aSMatthew Knepley PetscFunctionBegin; 3324*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 3325*ea844a1aSMatthew Knepley *flg = s->useFieldOff; 3326*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3327*ea844a1aSMatthew Knepley } 3328*ea844a1aSMatthew Knepley 3329*ea844a1aSMatthew Knepley /*@ 3330*ea844a1aSMatthew Knepley PetscSectionSetUseFieldOffsets - Set the flag to use field offsets directly in a global section, rather than just the point offset 3331*ea844a1aSMatthew Knepley 3332*ea844a1aSMatthew Knepley Not collective 3333*ea844a1aSMatthew Knepley 3334*ea844a1aSMatthew Knepley Input Parameters: 3335*ea844a1aSMatthew Knepley + s - the global PetscSection 3336*ea844a1aSMatthew Knepley - flg - the flag 3337*ea844a1aSMatthew Knepley 3338*ea844a1aSMatthew Knepley Level: developer 3339*ea844a1aSMatthew Knepley 3340*ea844a1aSMatthew Knepley .seealso: PetscSectionGetUseFieldOffsets(), PetscSectionSetChart(), PetscSectionCreate() 3341*ea844a1aSMatthew Knepley @*/ 3342*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionSetUseFieldOffsets(PetscSection s, PetscBool flg) 3343*ea844a1aSMatthew Knepley { 3344*ea844a1aSMatthew Knepley PetscFunctionBegin; 3345*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 3346*ea844a1aSMatthew Knepley s->useFieldOff = flg; 3347*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3348*ea844a1aSMatthew Knepley } 3349*ea844a1aSMatthew Knepley 3350*ea844a1aSMatthew Knepley #define PetscSectionExpandPoints_Loop(TYPE) \ 3351*ea844a1aSMatthew Knepley { \ 3352*ea844a1aSMatthew Knepley PetscInt i, n, o0, o1, size; \ 3353*ea844a1aSMatthew Knepley TYPE *a0 = (TYPE*)origArray, *a1; \ 3354*ea844a1aSMatthew Knepley ierr = PetscSectionGetStorageSize(s, &size);CHKERRQ(ierr); \ 3355*ea844a1aSMatthew Knepley ierr = PetscMalloc1(size, &a1);CHKERRQ(ierr); \ 3356*ea844a1aSMatthew Knepley for (i=0; i<npoints; i++) { \ 3357*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(origSection, points_[i], &o0);CHKERRQ(ierr); \ 3358*ea844a1aSMatthew Knepley ierr = PetscSectionGetOffset(s, i, &o1);CHKERRQ(ierr); \ 3359*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(s, i, &n);CHKERRQ(ierr); \ 3360*ea844a1aSMatthew Knepley ierr = PetscMemcpy(&a1[o1], &a0[o0], n*unitsize);CHKERRQ(ierr); \ 3361*ea844a1aSMatthew Knepley } \ 3362*ea844a1aSMatthew Knepley *newArray = (void*)a1; \ 3363*ea844a1aSMatthew Knepley } 3364*ea844a1aSMatthew Knepley 3365*ea844a1aSMatthew Knepley /*@ 3366*ea844a1aSMatthew Knepley PetscSectionExtractDofsFromArray - Extracts elements of an array corresponding to DOFs of specified points. 3367*ea844a1aSMatthew Knepley 3368*ea844a1aSMatthew Knepley Not collective 3369*ea844a1aSMatthew Knepley 3370*ea844a1aSMatthew Knepley Input Parameters: 3371*ea844a1aSMatthew Knepley + origSection - the PetscSection describing the layout of the array 3372*ea844a1aSMatthew Knepley . dataType - MPI_Datatype describing the data type of the array (currently only MPIU_INT, MPIU_SCALAR, MPIU_REAL) 3373*ea844a1aSMatthew Knepley . origArray - the array; its size must be equal to the storage size of origSection 3374*ea844a1aSMatthew Knepley - points - IS with points to extract; its indices must lie in the chart of origSection 3375*ea844a1aSMatthew Knepley 3376*ea844a1aSMatthew Knepley Output Parameters: 3377*ea844a1aSMatthew Knepley + newSection - the new PetscSection desribing the layout of the new array (with points renumbered 0,1,... but preserving numbers of DOFs) 3378*ea844a1aSMatthew Knepley - newArray - the array of the extracted DOFs; its size is the storage size of newSection 3379*ea844a1aSMatthew Knepley 3380*ea844a1aSMatthew Knepley Level: developer 3381*ea844a1aSMatthew Knepley 3382*ea844a1aSMatthew Knepley .seealso: PetscSectionGetChart(), PetscSectionGetDof(), PetscSectionGetStorageSize(), PetscSectionCreate() 3383*ea844a1aSMatthew Knepley @*/ 3384*ea844a1aSMatthew Knepley PetscErrorCode PetscSectionExtractDofsFromArray(PetscSection origSection, MPI_Datatype dataType, const void *origArray, IS points, PetscSection *newSection, void *newArray[]) 3385*ea844a1aSMatthew Knepley { 3386*ea844a1aSMatthew Knepley PetscSection s; 3387*ea844a1aSMatthew Knepley const PetscInt *points_; 3388*ea844a1aSMatthew Knepley PetscInt i, n, npoints, pStart, pEnd; 3389*ea844a1aSMatthew Knepley PetscMPIInt unitsize; 3390*ea844a1aSMatthew Knepley PetscErrorCode ierr; 3391*ea844a1aSMatthew Knepley 3392*ea844a1aSMatthew Knepley PetscFunctionBegin; 3393*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(origSection, PETSC_SECTION_CLASSID, 1); 3394*ea844a1aSMatthew Knepley PetscValidPointer(origArray, 3); 3395*ea844a1aSMatthew Knepley PetscValidHeaderSpecific(points, IS_CLASSID, 4); 3396*ea844a1aSMatthew Knepley if (newSection) PetscValidPointer(newSection, 5); 3397*ea844a1aSMatthew Knepley if (newArray) PetscValidPointer(newArray, 6); 3398*ea844a1aSMatthew Knepley ierr = MPI_Type_size(dataType, &unitsize);CHKERRQ(ierr); 3399*ea844a1aSMatthew Knepley ierr = ISGetLocalSize(points, &npoints);CHKERRQ(ierr); 3400*ea844a1aSMatthew Knepley ierr = ISGetIndices(points, &points_);CHKERRQ(ierr); 3401*ea844a1aSMatthew Knepley ierr = PetscSectionGetChart(origSection, &pStart, &pEnd);CHKERRQ(ierr); 3402*ea844a1aSMatthew Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 3403*ea844a1aSMatthew Knepley ierr = PetscSectionSetChart(s, 0, npoints);CHKERRQ(ierr); 3404*ea844a1aSMatthew Knepley for (i=0; i<npoints; i++) { 3405*ea844a1aSMatthew Knepley if (PetscUnlikely(points_[i] < pStart || points_[i] >= pEnd)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "point %d (index %d) in input IS out of input section's chart", points_[i], i); 3406*ea844a1aSMatthew Knepley ierr = PetscSectionGetDof(origSection, points_[i], &n);CHKERRQ(ierr); 3407*ea844a1aSMatthew Knepley ierr = PetscSectionSetDof(s, i, n);CHKERRQ(ierr); 3408*ea844a1aSMatthew Knepley } 3409*ea844a1aSMatthew Knepley ierr = PetscSectionSetUp(s);CHKERRQ(ierr); 3410*ea844a1aSMatthew Knepley if (newArray) { 3411*ea844a1aSMatthew Knepley if (dataType == MPIU_INT) {PetscSectionExpandPoints_Loop(PetscInt);} 3412*ea844a1aSMatthew Knepley else if (dataType == MPIU_SCALAR) {PetscSectionExpandPoints_Loop(PetscScalar);} 3413*ea844a1aSMatthew Knepley else if (dataType == MPIU_REAL) {PetscSectionExpandPoints_Loop(PetscReal);} 3414*ea844a1aSMatthew Knepley else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "not implemented for this MPI_Datatype"); 3415*ea844a1aSMatthew Knepley } 3416*ea844a1aSMatthew Knepley if (newSection) { 3417*ea844a1aSMatthew Knepley *newSection = s; 3418*ea844a1aSMatthew Knepley } else { 3419*ea844a1aSMatthew Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 3420*ea844a1aSMatthew Knepley } 3421*ea844a1aSMatthew Knepley PetscFunctionReturn(0); 3422*ea844a1aSMatthew Knepley } 3423