19f6c5813SMatthew G. Knepley #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabelephemeral.h" I*/ 29f6c5813SMatthew G. Knepley #include <petscdmlabelephemeral.h> 39f6c5813SMatthew G. Knepley 49f6c5813SMatthew G. Knepley /* 59f6c5813SMatthew G. Knepley An emphemeral label is read-only 69f6c5813SMatthew G. Knepley 79f6c5813SMatthew G. Knepley This initial implementation makes the assumption that the produced points have unique parents. If this is 89f6c5813SMatthew G. Knepley not satisfied, hash tables can be introduced to ensure produced points are unique. 99f6c5813SMatthew G. Knepley */ 109f6c5813SMatthew G. Knepley 119f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelEphemeralComputeStratumSize_Private(DMLabel label, PetscInt value) 129f6c5813SMatthew G. Knepley { 139f6c5813SMatthew G. Knepley DMPlexTransform tr; 149f6c5813SMatthew G. Knepley DM dm; 159f6c5813SMatthew G. Knepley DMLabel olabel; 169f6c5813SMatthew G. Knepley IS opointIS; 179f6c5813SMatthew G. Knepley const PetscInt *opoints; 189f6c5813SMatthew G. Knepley PetscInt Np = 0, Nop, op, v; 199f6c5813SMatthew G. Knepley 209f6c5813SMatthew G. Knepley PetscFunctionBegin; 219f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetTransform(label, &tr)); 229f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetLabel(label, &olabel)); 239f6c5813SMatthew G. Knepley PetscCall(DMPlexTransformGetDM(tr, &dm)); 249f6c5813SMatthew G. Knepley 259f6c5813SMatthew G. Knepley PetscCall(DMLabelLookupStratum(olabel, value, &v)); 269f6c5813SMatthew G. Knepley PetscCall(DMLabelGetStratumIS(olabel, value, &opointIS)); 279f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(opointIS, &Nop)); 289f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(opointIS, &opoints)); 299f6c5813SMatthew G. Knepley for (op = 0; op < Nop; ++op) { 309f6c5813SMatthew G. Knepley const PetscInt point = opoints[op]; 319f6c5813SMatthew G. Knepley DMPolytopeType ct; 329f6c5813SMatthew G. Knepley DMPolytopeType *rct; 339f6c5813SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 349f6c5813SMatthew G. Knepley PetscInt Nct; 359f6c5813SMatthew G. Knepley 369f6c5813SMatthew G. Knepley PetscCall(DMPlexGetCellType(dm, point, &ct)); 379f6c5813SMatthew G. Knepley PetscCall(DMPlexTransformCellTransform(tr, ct, point, NULL, &Nct, &rct, &rsize, &rcone, &rornt)); 389f6c5813SMatthew G. Knepley for (PetscInt n = 0; n < Nct; ++n) Np += rsize[n]; 399f6c5813SMatthew G. Knepley } 409f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(opointIS, &opoints)); 419f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&opointIS)); 429f6c5813SMatthew G. Knepley label->stratumSizes[v] = Np; 433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 449f6c5813SMatthew G. Knepley } 459f6c5813SMatthew G. Knepley 469f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelGetStratumIS_Ephemeral(DMLabel label, PetscInt v, IS *stratum) 479f6c5813SMatthew G. Knepley { 489f6c5813SMatthew G. Knepley DMPlexTransform tr; 499f6c5813SMatthew G. Knepley DM dm; 509f6c5813SMatthew G. Knepley DMLabel olabel; 519f6c5813SMatthew G. Knepley IS opointIS; 529f6c5813SMatthew G. Knepley const PetscInt *opoints; 539f6c5813SMatthew G. Knepley PetscInt *points; 549f6c5813SMatthew G. Knepley PetscInt Np, p, Nop, op; 559f6c5813SMatthew G. Knepley 569f6c5813SMatthew G. Knepley PetscFunctionBegin; 579f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetTransform(label, &tr)); 589f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetLabel(label, &olabel)); 599f6c5813SMatthew G. Knepley PetscCall(DMPlexTransformGetDM(tr, &dm)); 609f6c5813SMatthew G. Knepley 619f6c5813SMatthew G. Knepley PetscCall(DMLabelGetStratumSize_Private(label, v, &Np)); 629f6c5813SMatthew G. Knepley PetscCall(PetscMalloc1(Np, &points)); 639f6c5813SMatthew G. Knepley PetscUseTypeMethod(olabel, getstratumis, v, &opointIS); 649f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(opointIS, &Nop)); 659f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(opointIS, &opoints)); 669f6c5813SMatthew G. Knepley for (op = 0, p = 0; op < Nop; ++op) { 679f6c5813SMatthew G. Knepley const PetscInt point = opoints[op]; 689f6c5813SMatthew G. Knepley DMPolytopeType ct; 699f6c5813SMatthew G. Knepley DMPolytopeType *rct; 709f6c5813SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 719f6c5813SMatthew G. Knepley PetscInt Nct, n, r, pNew = 0; 729f6c5813SMatthew G. Knepley 739f6c5813SMatthew G. Knepley PetscCall(DMPlexGetCellType(dm, point, &ct)); 749f6c5813SMatthew G. Knepley PetscCall(DMPlexTransformCellTransform(tr, ct, point, NULL, &Nct, &rct, &rsize, &rcone, &rornt)); 759f6c5813SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 769f6c5813SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 779f6c5813SMatthew G. Knepley PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], point, r, &pNew)); 789f6c5813SMatthew G. Knepley points[p++] = pNew; 799f6c5813SMatthew G. Knepley } 809f6c5813SMatthew G. Knepley } 819f6c5813SMatthew G. Knepley } 829f6c5813SMatthew G. Knepley PetscCheck(p == Np, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Number of stratum points %" PetscInt_FMT " != %" PetscInt_FMT " precomputed size", p, Np); 839f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(opointIS, &opoints)); 849f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&opointIS)); 859f6c5813SMatthew G. Knepley PetscCall(ISCreateGeneral(PETSC_COMM_SELF, Np, points, PETSC_OWN_POINTER, stratum)); 863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 879f6c5813SMatthew G. Knepley } 889f6c5813SMatthew G. Knepley 899f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelSetUp_Ephemeral(DMLabel label) 909f6c5813SMatthew G. Knepley { 919f6c5813SMatthew G. Knepley DMLabel olabel; 929f6c5813SMatthew G. Knepley IS valueIS; 939f6c5813SMatthew G. Knepley const PetscInt *values; 949f6c5813SMatthew G. Knepley PetscInt defValue, Nv; 959f6c5813SMatthew G. Knepley 969f6c5813SMatthew G. Knepley PetscFunctionBegin; 979f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetLabel(label, &olabel)); 989f6c5813SMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(olabel, &defValue)); 999f6c5813SMatthew G. Knepley PetscCall(DMLabelSetDefaultValue(label, defValue)); 1009f6c5813SMatthew G. Knepley PetscCall(DMLabelGetNumValues(olabel, &Nv)); 1019f6c5813SMatthew G. Knepley PetscCall(DMLabelGetValueIS(olabel, &valueIS)); 1029f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(valueIS, &values)); 1039f6c5813SMatthew G. Knepley PetscCall(DMLabelAddStrataIS(label, valueIS)); 1049f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < Nv; ++v) PetscCall(DMLabelEphemeralComputeStratumSize_Private(label, values[v])); 1059f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(valueIS, &values)); 1069f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&valueIS)); 1079f6c5813SMatthew G. Knepley label->readonly = PETSC_TRUE; 1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1099f6c5813SMatthew G. Knepley } 1109f6c5813SMatthew G. Knepley 1119f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Ephemeral_Ascii(DMLabel label, PetscViewer viewer) 1129f6c5813SMatthew G. Knepley { 1139f6c5813SMatthew G. Knepley DMLabel olabel; 1149f6c5813SMatthew G. Knepley PetscMPIInt rank; 1159f6c5813SMatthew G. Knepley 1169f6c5813SMatthew G. Knepley PetscFunctionBegin; 1179f6c5813SMatthew G. Knepley PetscCall(DMLabelEphemeralGetLabel(label, &olabel)); 1189f6c5813SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 1199f6c5813SMatthew G. Knepley PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 1209f6c5813SMatthew G. Knepley if (olabel) { 1219f6c5813SMatthew G. Knepley IS valueIS; 1229f6c5813SMatthew G. Knepley const PetscInt *values; 1239f6c5813SMatthew G. Knepley PetscInt Nv, v; 1249f6c5813SMatthew G. Knepley const char *name; 1259f6c5813SMatthew G. Knepley 1269f6c5813SMatthew G. Knepley PetscCall(PetscObjectGetName((PetscObject)label, &name)); 1279f6c5813SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "Ephemeral Label '%s':\n", name)); 1289f6c5813SMatthew G. Knepley PetscCall(DMLabelGetNumValues(olabel, &Nv)); 1299f6c5813SMatthew G. Knepley PetscCall(DMLabelGetValueIS(olabel, &valueIS)); 1309f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(valueIS, &values)); 1319f6c5813SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 1329f6c5813SMatthew G. Knepley IS pointIS; 1339f6c5813SMatthew G. Knepley const PetscInt value = values[v]; 1349f6c5813SMatthew G. Knepley const PetscInt *points; 1359f6c5813SMatthew G. Knepley PetscInt n, p; 1369f6c5813SMatthew G. Knepley 1379f6c5813SMatthew G. Knepley PetscCall(DMLabelGetStratumIS(olabel, value, &pointIS)); 1389f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 1399f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(pointIS, &n)); 1409f6c5813SMatthew G. Knepley for (p = 0; p < n; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 1419f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &points)); 1429f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 1439f6c5813SMatthew G. Knepley } 1449f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(valueIS, &values)); 1459f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&valueIS)); 1469f6c5813SMatthew G. Knepley } 1479f6c5813SMatthew G. Knepley PetscCall(PetscViewerFlush(viewer)); 1489f6c5813SMatthew G. Knepley PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 1493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1509f6c5813SMatthew G. Knepley } 1519f6c5813SMatthew G. Knepley 1529f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Ephemeral(DMLabel label, PetscViewer viewer) 1539f6c5813SMatthew G. Knepley { 1549f6c5813SMatthew G. Knepley PetscBool iascii; 1559f6c5813SMatthew G. Knepley 1569f6c5813SMatthew G. Knepley PetscFunctionBegin; 1579f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1589f6c5813SMatthew G. Knepley if (iascii) PetscCall(DMLabelView_Ephemeral_Ascii(label, viewer)); 1593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1609f6c5813SMatthew G. Knepley } 1619f6c5813SMatthew G. Knepley 1629f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelDuplicate_Ephemeral(DMLabel label, DMLabel *labelnew) 1639f6c5813SMatthew G. Knepley { 1649f6c5813SMatthew G. Knepley PetscObject olabel; 1659f6c5813SMatthew G. Knepley 1669f6c5813SMatthew G. Knepley PetscFunctionBegin; 1679f6c5813SMatthew G. Knepley PetscCall(PetscObjectQuery((PetscObject)label, "__original_label__", &olabel)); 1689f6c5813SMatthew G. Knepley PetscCall(PetscObjectCompose((PetscObject)*labelnew, "__original_label__", olabel)); 1693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1709f6c5813SMatthew G. Knepley } 1719f6c5813SMatthew G. Knepley 1729f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Ephemeral(DMLabel label) 1739f6c5813SMatthew G. Knepley { 1749f6c5813SMatthew G. Knepley PetscFunctionBegin; 1759f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Ephemeral; 1769f6c5813SMatthew G. Knepley label->ops->setup = DMLabelSetUp_Ephemeral; 1779f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Ephemeral; 1789f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Ephemeral; 1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1809f6c5813SMatthew G. Knepley } 1819f6c5813SMatthew G. Knepley 1829f6c5813SMatthew G. Knepley /*MC 1839f6c5813SMatthew G. Knepley DMLABELEPHEMERAL = "ephemeral" - This type of `DMLabel` is used to label ephemeral meshes. 1849f6c5813SMatthew G. Knepley 1859f6c5813SMatthew G. Knepley Ephemeral meshes are never concretely instantiated, but rather the answers to queries are created on the fly from a base mesh and a `DMPlexTransform` object. 1869f6c5813SMatthew G. Knepley For example, we could integrate over a refined mesh without ever storing the entire thing, just producing each cell closure one at a time. The label consists 1879f6c5813SMatthew G. Knepley of a base label and the same transform. Stratum are produced on demand, so that the time is in $O(max(M, N))$ where $M$ is the size of the original stratum, 1889f6c5813SMatthew G. Knepley and $N$ is the size of the output stratum. Queries take the same time, since we cannot sort the output. 1899f6c5813SMatthew G. Knepley 1909f6c5813SMatthew G. Knepley Level: intermediate 1919f6c5813SMatthew G. Knepley 1929f6c5813SMatthew G. Knepley .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelCreate()`, `DMLabelSetType()` 1939f6c5813SMatthew G. Knepley M*/ 1949f6c5813SMatthew G. Knepley 1959f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel label) 1969f6c5813SMatthew G. Knepley { 1979f6c5813SMatthew G. Knepley PetscFunctionBegin; 1989f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1999f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Ephemeral(label)); 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2019f6c5813SMatthew G. Knepley } 2029f6c5813SMatthew G. Knepley 2039f6c5813SMatthew G. Knepley /*@ 2049f6c5813SMatthew G. Knepley DMLabelEphemeralGetLabel - Get the base label for this ephemeral label 2059f6c5813SMatthew G. Knepley 20620f4b53cSBarry Smith Not Collective 2079f6c5813SMatthew G. Knepley 2089f6c5813SMatthew G. Knepley Input Parameter: 20920f4b53cSBarry Smith . label - the `DMLabel` 2109f6c5813SMatthew G. Knepley 211*aaa8cc7dSPierre Jolivet Output Parameter: 2129f6c5813SMatthew G. Knepley . olabel - the base label for this ephemeral label 2139f6c5813SMatthew G. Knepley 21420f4b53cSBarry Smith Level: intermediate 21520f4b53cSBarry Smith 2169f6c5813SMatthew G. Knepley Note: 2179f6c5813SMatthew G. Knepley Ephemeral labels are produced automatically from a base label and a `DMPlexTransform`. 2189f6c5813SMatthew G. Knepley 2199f6c5813SMatthew G. Knepley .seealso: `DMLabelEphemeralSetLabel()`, `DMLabelEphemeralGetTransform()`, `DMLabelSetType()` 2209f6c5813SMatthew G. Knepley @*/ 2219f6c5813SMatthew G. Knepley PetscErrorCode DMLabelEphemeralGetLabel(DMLabel label, DMLabel *olabel) 2229f6c5813SMatthew G. Knepley { 2239f6c5813SMatthew G. Knepley PetscFunctionBegin; 2249f6c5813SMatthew G. Knepley PetscCall(PetscObjectQuery((PetscObject)label, "__original_label__", (PetscObject *)olabel)); 2253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2269f6c5813SMatthew G. Knepley } 2279f6c5813SMatthew G. Knepley 2289f6c5813SMatthew G. Knepley /*@ 2299f6c5813SMatthew G. Knepley DMLabelEphemeralSetLabel - Set the base label for this ephemeral label 2309f6c5813SMatthew G. Knepley 23120f4b53cSBarry Smith Not Collective 2329f6c5813SMatthew G. Knepley 2339f6c5813SMatthew G. Knepley Input Parameters: 23420f4b53cSBarry Smith + label - the `DMLabel` 2359f6c5813SMatthew G. Knepley - olabel - the base label for this ephemeral label 2369f6c5813SMatthew G. Knepley 23720f4b53cSBarry Smith Level: intermediate 23820f4b53cSBarry Smith 2399f6c5813SMatthew G. Knepley Note: 2409f6c5813SMatthew G. Knepley Ephemeral labels are produced automatically from a base label and a `DMPlexTransform`. 2419f6c5813SMatthew G. Knepley 2429f6c5813SMatthew G. Knepley .seealso: `DMLabelEphemeralGetLabel()`, `DMLabelEphemeralSetTransform()`, `DMLabelSetType()` 2439f6c5813SMatthew G. Knepley @*/ 2449f6c5813SMatthew G. Knepley PetscErrorCode DMLabelEphemeralSetLabel(DMLabel label, DMLabel olabel) 2459f6c5813SMatthew G. Knepley { 2469f6c5813SMatthew G. Knepley PetscFunctionBegin; 2479f6c5813SMatthew G. Knepley PetscCall(PetscObjectCompose((PetscObject)label, "__original_label__", (PetscObject)olabel)); 2483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2499f6c5813SMatthew G. Knepley } 250