PetscErrorCode DMPlexGetAdjacency_Internal(DM dm, PetscInt p, PetscBool useCone, PetscBool useTransitiveClosure, PetscInt *adjSize, PetscInt *adj[]) { static PetscInt asiz = 0; PetscErrorCode ierr; PetscFunctionBeginHot; if (!*adj) { PetscInt depth, maxConeSize, maxSupportSize; ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); asiz = PetscPowInt(maxConeSize, depth+1) * PetscPowInt(maxSupportSize, depth+1) + 1; ierr = PetscMalloc1(asiz,adj);CHKERRQ(ierr); } if (*adjSize < 0) *adjSize = asiz; if (useTransitiveClosure) { ierr = DMPlexGetAdjacency_Transitive_Internal(dm, p, useCone, adjSize, *adj);CHKERRQ(ierr); } else if (useCone) { ierr = DMPlexGetAdjacency_Cone_Internal(dm, p, adjSize, *adj);CHKERRQ(ierr); } else { ierr = DMPlexGetAdjacency_Support_Internal(dm, p, adjSize, *adj);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode DMPlexGetAdjacency_Internal(DM dm, PetscInt p, PetscBool useCone, PetscBool useTransitiveClosure, PetscBool useAnchors, PetscInt *adjSize, PetscInt *adj[]) { static PetscInt asiz = 0; PetscInt maxAnchors = 1; PetscInt aStart = -1, aEnd = -1; PetscInt maxAdjSize; PetscSection aSec = NULL; IS aIS = NULL; const PetscInt *anchors; PetscErrorCode ierr; PetscFunctionBeginHot; if (useAnchors) { ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); if (aSec) { ierr = PetscSectionGetMaxDof(aSec,&maxAnchors);CHKERRQ(ierr); maxAnchors = PetscMax(1,maxAnchors); ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); } } if (!*adj) { PetscInt depth, coneSeries, supportSeries, maxC, maxS, pStart, pEnd; ierr = DMPlexGetChart(dm, &pStart,&pEnd);CHKERRQ(ierr); ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); ierr = DMPlexGetMaxSizes(dm, &maxC, &maxS);CHKERRQ(ierr); coneSeries = (maxC > 1) ? ((PetscPowInt(maxC,depth+1)-1)/(maxC-1)) : depth+1; supportSeries = (maxS > 1) ? ((PetscPowInt(maxS,depth+1)-1)/(maxS-1)) : depth+1; asiz = PetscMax(PetscPowInt(maxS,depth)*coneSeries,PetscPowInt(maxC,depth)*supportSeries); asiz *= maxAnchors; asiz = PetscMin(asiz,pEnd-pStart); ierr = PetscMalloc1(asiz,adj);CHKERRQ(ierr); } if (*adjSize < 0) *adjSize = asiz; maxAdjSize = *adjSize; if (useTransitiveClosure) { ierr = DMPlexGetAdjacency_Transitive_Internal(dm, p, useCone, adjSize, *adj);CHKERRQ(ierr); } else if (useCone) { ierr = DMPlexGetAdjacency_Cone_Internal(dm, p, adjSize, *adj);CHKERRQ(ierr); } else { ierr = DMPlexGetAdjacency_Support_Internal(dm, p, adjSize, *adj);CHKERRQ(ierr); } if (useAnchors && aSec) { PetscInt origSize = *adjSize; PetscInt numAdj = origSize; PetscInt i = 0, j; PetscInt *orig = *adj; while (i < origSize) { PetscInt p = orig[i]; PetscInt aDof = 0; if (p >= aStart && p < aEnd) { ierr = PetscSectionGetDof(aSec,p,&aDof);CHKERRQ(ierr); } if (aDof) { PetscInt aOff; PetscInt s, q; for (j = i + 1; j < numAdj; j++) { orig[j - 1] = orig[j]; } origSize--; numAdj--; ierr = PetscSectionGetOffset(aSec,p,&aOff);CHKERRQ(ierr); for (s = 0; s < aDof; ++s) { for (q = 0; q < numAdj || (orig[numAdj++] = anchors[aOff+s],0); ++q) { if (anchors[aOff+s] == orig[q]) break; } if (numAdj > maxAdjSize) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid mesh exceeded adjacency allocation (%D)", maxAdjSize); } } else { i++; } } *adjSize = numAdj; ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); } PetscFunctionReturn(0); }