/*@C DMPlexGetLabelIdIS - Get the integer ids in a label Not Collective Input Parameters: + mesh - The DMPlex object - name - The label name Output Parameter: . ids - The integer ids, or NULL if the label does not exist Level: beginner .keywords: mesh .seealso: DMLabelGetValueIS(), DMPlexGetLabelSize() @*/ PetscErrorCode DMPlexGetLabelIdIS(DM dm, const char name[], IS *ids) { DMLabel label; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm, DM_CLASSID, 1); PetscValidCharPointer(name, 2); PetscValidPointer(ids, 3); ierr = DMPlexGetLabel(dm, name, &label);CHKERRQ(ierr); *ids = NULL; if (!label) PetscFunctionReturn(0); ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) { IS vIS; const PetscInt *values; PetscInt *points; PetscInt nV, vS = 0, vE = 0, v, N; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); if (nV) {vS = values[0]; vE = values[0]+1;} for (v = 1; v < nV; ++v) { vS = PetscMin(vS, values[v]); vE = PetscMax(vE, values[v]+1); } ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); for (v = 0; v < nV; ++v) { PetscInt n; ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); } ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); for (v = 0; v < nV; ++v) { IS is; const PetscInt *spoints; PetscInt dof, off, p; ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); } ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); ierr = ISDestroy(&vIS);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ DMPlexGetOrdering - Calculate a reordering of the mesh Collective on DM Input Parameter: + dm - The DMPlex object . otype - type of reordering, one of the following: $ MATORDERINGNATURAL - Natural $ MATORDERINGND - Nested Dissection $ MATORDERING1WD - One-way Dissection $ MATORDERINGRCM - Reverse Cuthill-McKee $ MATORDERINGQMD - Quotient Minimum Degree - label - [Optional] Label used to segregate ordering into sets, or NULL Output Parameter: . perm - The point permutation as an IS, perm[old point number] = new point number Note: The label is used to group sets of points together by label value. This makes it easy to reorder a mesh which has different types of cells, and then loop over each set of reordered cells for assembly. Level: intermediate .keywords: mesh .seealso: MatGetOrdering() @*/ PetscErrorCode DMPlexGetOrdering(DM dm, MatOrderingType otype, DMLabel label, IS *perm) { PetscInt numCells = 0; PetscInt *start = NULL, *adjacency = NULL, *cperm, *clperm, *invclperm, *mask, *xls, pStart, pEnd, c, i; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm, DM_CLASSID, 1); PetscValidPointer(perm, 3); ierr = DMPlexCreateNeighborCSR(dm, 0, &numCells, &start, &adjacency);CHKERRQ(ierr); ierr = PetscMalloc3(numCells,&cperm,numCells,&mask,numCells*2,&xls);CHKERRQ(ierr); if (numCells) { /* Shift for Fortran numbering */ for (i = 0; i < start[numCells]; ++i) ++adjacency[i]; for (i = 0; i <= numCells; ++i) ++start[i]; ierr = SPARSEPACKgenrcm(&numCells, start, adjacency, cperm, mask, xls);CHKERRQ(ierr); } ierr = PetscFree(start);CHKERRQ(ierr); ierr = PetscFree(adjacency);CHKERRQ(ierr); /* Shift for Fortran numbering */ for (c = 0; c < numCells; ++c) --cperm[c]; /* Segregate */ if (label) { IS valueIS; const PetscInt *values; PetscInt numValues, numPoints = 0; PetscInt *sperm, *vsize, *voff, v; ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); ierr = ISSort(valueIS);CHKERRQ(ierr); ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); ierr = PetscCalloc3(numCells,&sperm,numValues,&vsize,numValues+1,&voff);CHKERRQ(ierr); for (v = 0; v < numValues; ++v) { ierr = DMLabelGetStratumSize(label, values[v], &vsize[v]);CHKERRQ(ierr); if (v < numValues-1) voff[v+2] += vsize[v] + voff[v+1]; numPoints += vsize[v]; } if (numPoints != numCells) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label only covers %D cells < %D total", numPoints, numCells); for (c = 0; c < numCells; ++c) { const PetscInt oldc = cperm[c]; PetscInt val, vloc; ierr = DMLabelGetValue(label, oldc, &val);CHKERRQ(ierr); if (val == -1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cell %D not present in label", oldc); ierr = PetscFindInt(val, numValues, values, &vloc);CHKERRQ(ierr); if (vloc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Value %D not present label", val); sperm[voff[vloc+1]++] = oldc; } for (v = 0; v < numValues; ++v) { if (voff[v+1] - voff[v] != vsize[v]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of %D values found is %D != %D", values[v], voff[v+1] - voff[v], vsize[v]); } ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); ierr = ISDestroy(&valueIS);CHKERRQ(ierr); ierr = PetscMemcpy(cperm, sperm, numCells * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscFree3(sperm, vsize, voff);CHKERRQ(ierr); } /* Construct closure */ ierr = DMPlexCreateOrderingClosure_Static(dm, numCells, cperm, &clperm, &invclperm);CHKERRQ(ierr); ierr = PetscFree3(cperm,mask,xls);CHKERRQ(ierr); ierr = PetscFree(clperm);CHKERRQ(ierr); /* Invert permutation */ ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd-pStart, invclperm, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); PetscFunctionReturn(0); }