xref: /petsc/src/dm/label/impls/ephemeral/dmlabeleph.c (revision aaa8cc7d2a5c3913edcbb923e20f154fe9c4aa65)
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