18135c375SStefano Zampini #include <petsc/private/glvisviewerimpl.h> 28135c375SStefano Zampini #include <petsc/private/petscimpl.h> 38135c375SStefano Zampini #include <petsc/private/dmpleximpl.h> 48135c375SStefano Zampini #include <petscbt.h> 58135c375SStefano Zampini #include <petscdmplex.h> 68135c375SStefano Zampini #include <petscsf.h> 78135c375SStefano Zampini #include <petscds.h> 88135c375SStefano Zampini 98135c375SStefano Zampini typedef struct { 108135c375SStefano Zampini PetscInt nf; 118135c375SStefano Zampini VecScatter *scctx; 128135c375SStefano Zampini } GLVisViewerCtx; 138135c375SStefano Zampini 149371c9d4SSatish Balay static PetscErrorCode DestroyGLVisViewerCtx_Private(void *vctx) { 158135c375SStefano Zampini GLVisViewerCtx *ctx = (GLVisViewerCtx *)vctx; 168135c375SStefano Zampini PetscInt i; 178135c375SStefano Zampini 188135c375SStefano Zampini PetscFunctionBegin; 19*48a46eb9SPierre Jolivet for (i = 0; i < ctx->nf; i++) PetscCall(VecScatterDestroy(&ctx->scctx[i])); 209566063dSJacob Faibussowitsch PetscCall(PetscFree(ctx->scctx)); 219566063dSJacob Faibussowitsch PetscCall(PetscFree(vctx)); 228135c375SStefano Zampini PetscFunctionReturn(0); 238135c375SStefano Zampini } 248135c375SStefano Zampini 259371c9d4SSatish Balay static PetscErrorCode DMPlexSampleGLVisFields_Private(PetscObject oX, PetscInt nf, PetscObject oXfield[], void *vctx) { 268135c375SStefano Zampini GLVisViewerCtx *ctx = (GLVisViewerCtx *)vctx; 278135c375SStefano Zampini PetscInt f; 288135c375SStefano Zampini 298135c375SStefano Zampini PetscFunctionBegin; 308135c375SStefano Zampini for (f = 0; f < nf; f++) { 319566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ctx->scctx[f], (Vec)oX, (Vec)oXfield[f], INSERT_VALUES, SCATTER_FORWARD)); 329566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ctx->scctx[f], (Vec)oX, (Vec)oXfield[f], INSERT_VALUES, SCATTER_FORWARD)); 338135c375SStefano Zampini } 348135c375SStefano Zampini PetscFunctionReturn(0); 358135c375SStefano Zampini } 368135c375SStefano Zampini 378135c375SStefano Zampini /* for FEM, it works for H1 fields only and extracts dofs at cell vertices, discarding any other dof */ 389371c9d4SSatish Balay PetscErrorCode DMSetUpGLVisViewer_Plex(PetscObject odm, PetscViewer viewer) { 398135c375SStefano Zampini DM dm = (DM)odm; 404cac2994SStefano Zampini Vec xlocal, xfield, *Ufield; 418135c375SStefano Zampini PetscDS ds; 428135c375SStefano Zampini IS globalNum, isfield; 438135c375SStefano Zampini PetscBT vown; 448135c375SStefano Zampini char **fieldname = NULL, **fec_type = NULL; 458135c375SStefano Zampini const PetscInt *gNum; 46bb77a09fSStefano Zampini PetscInt *nlocal, *bs, *idxs, *dims; 478135c375SStefano Zampini PetscInt f, maxfields, nfields, c, totc, totdofs, Nv, cum, i; 48b135d7daSStefano Zampini PetscInt dim, cStart, cEnd, vStart, vEnd; 498135c375SStefano Zampini GLVisViewerCtx *ctx; 508135c375SStefano Zampini PetscSection s; 518135c375SStefano Zampini 528135c375SStefano Zampini PetscFunctionBegin; 539566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 549566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 559566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 569566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "_glvis_plex_gnum", (PetscObject *)&globalNum)); 57b135d7daSStefano Zampini if (!globalNum) { 589566063dSJacob Faibussowitsch PetscCall(DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &globalNum)); 599566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)dm, "_glvis_plex_gnum", (PetscObject)globalNum)); 609566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)globalNum)); 61b135d7daSStefano Zampini } 629566063dSJacob Faibussowitsch PetscCall(ISGetIndices(globalNum, &gNum)); 639566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(vEnd - vStart, &vown)); 648135c375SStefano Zampini for (c = cStart, totc = 0; c < cEnd; c++) { 658135c375SStefano Zampini if (gNum[c - cStart] >= 0) { 668135c375SStefano Zampini PetscInt i, numPoints, *points = NULL; 678135c375SStefano Zampini 688135c375SStefano Zampini totc++; 699566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &numPoints, &points)); 708135c375SStefano Zampini for (i = 0; i < numPoints * 2; i += 2) { 71*48a46eb9SPierre Jolivet if ((points[i] >= vStart) && (points[i] < vEnd)) PetscCall(PetscBTSet(vown, points[i] - vStart)); 728135c375SStefano Zampini } 739566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &numPoints, &points)); 748135c375SStefano Zampini } 758135c375SStefano Zampini } 769371c9d4SSatish Balay for (f = 0, Nv = 0; f < vEnd - vStart; f++) 779371c9d4SSatish Balay if (PetscLikely(PetscBTLookup(vown, f))) Nv++; 788135c375SStefano Zampini 799566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm, &xlocal)); 809566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(xlocal, &totdofs)); 819566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &nfields)); 838135c375SStefano Zampini for (f = 0, maxfields = 0; f < nfields; f++) { 848135c375SStefano Zampini PetscInt bs; 858135c375SStefano Zampini 869566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &bs)); 878135c375SStefano Zampini maxfields += bs; 888135c375SStefano Zampini } 899566063dSJacob Faibussowitsch PetscCall(PetscCalloc7(maxfields, &fieldname, maxfields, &nlocal, maxfields, &bs, maxfields, &dims, maxfields, &fec_type, totdofs, &idxs, maxfields, &Ufield)); 909566063dSJacob Faibussowitsch PetscCall(PetscNew(&ctx)); 919566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxfields, &ctx->scctx)); 929566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 938135c375SStefano Zampini if (ds) { 948135c375SStefano Zampini for (f = 0; f < nfields; f++) { 958135c375SStefano Zampini const char *fname; 968135c375SStefano Zampini char name[256]; 978135c375SStefano Zampini PetscObject disc; 988135c375SStefano Zampini size_t len; 998135c375SStefano Zampini 1009566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(s, f, &fname)); 1019566063dSJacob Faibussowitsch PetscCall(PetscStrlen(fname, &len)); 1028135c375SStefano Zampini if (len) { 1039566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(name, fname)); 1048135c375SStefano Zampini } else { 10563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, 256, "Field%" PetscInt_FMT, f)); 1068135c375SStefano Zampini } 1079566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, f, &disc)); 1088135c375SStefano Zampini if (disc) { 1098135c375SStefano Zampini PetscClassId id; 1108135c375SStefano Zampini PetscInt Nc; 1118135c375SStefano Zampini char fec[64]; 1128135c375SStefano Zampini 1139566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 1148135c375SStefano Zampini if (id == PETSCFE_CLASSID) { 1158135c375SStefano Zampini PetscFE fem = (PetscFE)disc; 1168135c375SStefano Zampini PetscDualSpace sp; 1178135c375SStefano Zampini PetscDualSpaceType spname; 1188135c375SStefano Zampini PetscInt order; 1198135c375SStefano Zampini PetscBool islag, continuous, H1 = PETSC_TRUE; 1208135c375SStefano Zampini 1219566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 1229566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 1239566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetType(sp, &spname)); 1249566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(spname, PETSCDUALSPACELAGRANGE, &islag)); 12528b400f6SJacob Faibussowitsch PetscCheck(islag, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dual space"); 1269566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeGetContinuity(sp, &continuous)); 1279566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetOrder(sp, &order)); 12828d58a37SPierre Jolivet if (continuous && order > 0) { /* no support for high-order viz, still have to figure out the numbering */ 12963a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(fec, 64, "FiniteElementCollection: H1_%" PetscInt_FMT "D_P1", dim)); 1308135c375SStefano Zampini } else { 13163a3b9bcSJacob Faibussowitsch PetscCheck(continuous || !order, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Discontinuous space visualization currently unsupported for order %" PetscInt_FMT, order); 1328135c375SStefano Zampini H1 = PETSC_FALSE; 13363a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(fec, 64, "FiniteElementCollection: L2_%" PetscInt_FMT "D_P%" PetscInt_FMT, dim, order)); 1348135c375SStefano Zampini } 1359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &fieldname[ctx->nf])); 1368135c375SStefano Zampini bs[ctx->nf] = Nc; 137bb77a09fSStefano Zampini dims[ctx->nf] = dim; 1388135c375SStefano Zampini if (H1) { 1398135c375SStefano Zampini nlocal[ctx->nf] = Nc * Nv; 1409566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fec, &fec_type[ctx->nf])); 1419566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, Nv * Nc, &xfield)); 1428135c375SStefano Zampini for (i = 0, cum = 0; i < vEnd - vStart; i++) { 1438135c375SStefano Zampini PetscInt j, off; 1448135c375SStefano Zampini 1458135c375SStefano Zampini if (PetscUnlikely(!PetscBTLookup(vown, i))) continue; 1469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(s, i + vStart, f, &off)); 1478135c375SStefano Zampini for (j = 0; j < Nc; j++) idxs[cum++] = off + j; 1488135c375SStefano Zampini } 1499566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)xlocal), Nv * Nc, idxs, PETSC_USE_POINTER, &isfield)); 1508135c375SStefano Zampini } else { 1518135c375SStefano Zampini nlocal[ctx->nf] = Nc * totc; 1529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fec, &fec_type[ctx->nf])); 1539566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, Nc * totc, &xfield)); 1548135c375SStefano Zampini for (i = 0, cum = 0; i < cEnd - cStart; i++) { 1558135c375SStefano Zampini PetscInt j, off; 1568135c375SStefano Zampini 1578135c375SStefano Zampini if (PetscUnlikely(gNum[i] < 0)) continue; 1589566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(s, i + cStart, f, &off)); 1598135c375SStefano Zampini for (j = 0; j < Nc; j++) idxs[cum++] = off + j; 1608135c375SStefano Zampini } 1619566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)xlocal), totc * Nc, idxs, PETSC_USE_POINTER, &isfield)); 1628135c375SStefano Zampini } 1639566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(xlocal, isfield, xfield, NULL, &ctx->scctx[ctx->nf])); 1649566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xfield)); 1659566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isfield)); 1668135c375SStefano Zampini ctx->nf++; 1678135c375SStefano Zampini } else if (id == PETSCFV_CLASSID) { 1688135c375SStefano Zampini PetscInt c; 1698135c375SStefano Zampini 1709566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents((PetscFV)disc, &Nc)); 17163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(fec, 64, "FiniteElementCollection: L2_%" PetscInt_FMT "D_P0", dim)); 1728135c375SStefano Zampini for (c = 0; c < Nc; c++) { 1738135c375SStefano Zampini char comp[256]; 17463a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(comp, 256, "%s-Comp%" PetscInt_FMT, name, c)); 1759566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(comp, &fieldname[ctx->nf])); 1768135c375SStefano Zampini bs[ctx->nf] = 1; /* Does PetscFV support components with different block size? */ 1778135c375SStefano Zampini nlocal[ctx->nf] = totc; 178bb77a09fSStefano Zampini dims[ctx->nf] = dim; 1799566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fec, &fec_type[ctx->nf])); 1809566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, totc, &xfield)); 1818135c375SStefano Zampini for (i = 0, cum = 0; i < cEnd - cStart; i++) { 1828135c375SStefano Zampini PetscInt off; 1838135c375SStefano Zampini 1848135c375SStefano Zampini if (PetscUnlikely(gNum[i]) < 0) continue; 1859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(s, i + cStart, f, &off)); 1868135c375SStefano Zampini idxs[cum++] = off + c; 1878135c375SStefano Zampini } 1889566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)xlocal), totc, idxs, PETSC_USE_POINTER, &isfield)); 1899566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(xlocal, isfield, xfield, NULL, &ctx->scctx[ctx->nf])); 1909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xfield)); 1919566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isfield)); 1928135c375SStefano Zampini ctx->nf++; 1938135c375SStefano Zampini } 19463a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f); 19563a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing discretization for field %" PetscInt_FMT, f); 1968135c375SStefano Zampini } 1978135c375SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Needs a DS attached to the DM"); 1989566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&vown)); 1999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xlocal)); 2009566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(globalNum, &gNum)); 2018135c375SStefano Zampini 2024cac2994SStefano Zampini /* create work vectors */ 2034cac2994SStefano Zampini for (f = 0; f < ctx->nf; f++) { 2049566063dSJacob Faibussowitsch PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)dm), nlocal[f], PETSC_DECIDE, &Ufield[f])); 2059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Ufield[f], fieldname[f])); 2069566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(Ufield[f], bs[f])); 2079566063dSJacob Faibussowitsch PetscCall(VecSetDM(Ufield[f], dm)); 2084cac2994SStefano Zampini } 2094cac2994SStefano Zampini 2108135c375SStefano Zampini /* customize the viewer */ 2119566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisSetFields(viewer, ctx->nf, (const char **)fec_type, dims, DMPlexSampleGLVisFields_Private, (PetscObject *)Ufield, ctx, DestroyGLVisViewerCtx_Private)); 2128135c375SStefano Zampini for (f = 0; f < ctx->nf; f++) { 2139566063dSJacob Faibussowitsch PetscCall(PetscFree(fieldname[f])); 2149566063dSJacob Faibussowitsch PetscCall(PetscFree(fec_type[f])); 2159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&Ufield[f])); 2168135c375SStefano Zampini } 2179566063dSJacob Faibussowitsch PetscCall(PetscFree7(fieldname, nlocal, bs, dims, fec_type, idxs, Ufield)); 2188135c375SStefano Zampini PetscFunctionReturn(0); 2198135c375SStefano Zampini } 2208135c375SStefano Zampini 2219371c9d4SSatish Balay typedef enum { 2229371c9d4SSatish Balay MFEM_POINT = 0, 2239371c9d4SSatish Balay MFEM_SEGMENT, 2249371c9d4SSatish Balay MFEM_TRIANGLE, 2259371c9d4SSatish Balay MFEM_SQUARE, 2269371c9d4SSatish Balay MFEM_TETRAHEDRON, 2279371c9d4SSatish Balay MFEM_CUBE, 2289371c9d4SSatish Balay MFEM_PRISM, 2299371c9d4SSatish Balay MFEM_UNDEF 2309371c9d4SSatish Balay } MFEM_cid; 2318135c375SStefano Zampini 2329371c9d4SSatish Balay MFEM_cid mfem_table_cid[4][7] = { 2339371c9d4SSatish Balay {MFEM_POINT, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF}, 2348135c375SStefano Zampini {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF}, 2358135c375SStefano Zampini {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_TRIANGLE, MFEM_SQUARE, MFEM_UNDEF, MFEM_UNDEF}, 2369371c9d4SSatish Balay {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_UNDEF, MFEM_TETRAHEDRON, MFEM_PRISM, MFEM_CUBE } 2379371c9d4SSatish Balay }; 2388135c375SStefano Zampini 2399371c9d4SSatish Balay MFEM_cid mfem_table_cid_unint[4][9] = { 2409371c9d4SSatish Balay {MFEM_POINT, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_PRISM, MFEM_UNDEF, MFEM_UNDEF}, 241b135d7daSStefano Zampini {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_UNDEF, MFEM_UNDEF, MFEM_UNDEF, MFEM_PRISM, MFEM_UNDEF, MFEM_UNDEF}, 242b135d7daSStefano Zampini {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_TRIANGLE, MFEM_SQUARE, MFEM_UNDEF, MFEM_PRISM, MFEM_UNDEF, MFEM_UNDEF}, 2439371c9d4SSatish Balay {MFEM_POINT, MFEM_UNDEF, MFEM_SEGMENT, MFEM_UNDEF, MFEM_TETRAHEDRON, MFEM_UNDEF, MFEM_PRISM, MFEM_UNDEF, MFEM_CUBE } 2449371c9d4SSatish Balay }; 245044a5661SStefano Zampini 2469371c9d4SSatish Balay static PetscErrorCode DMPlexGetPointMFEMCellID_Internal(DM dm, DMLabel label, PetscInt minl, PetscInt p, PetscInt *mid, PetscInt *cid) { 2478135c375SStefano Zampini DMLabel dlabel; 248044a5661SStefano Zampini PetscInt depth, csize, pdepth, dim; 2498135c375SStefano Zampini 2508135c375SStefano Zampini PetscFunctionBegin; 2519566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &dlabel)); 2529566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dlabel, p, &pdepth)); 2539566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, p, &csize)); 2549566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(dm, &depth)); 2559566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 2568135c375SStefano Zampini if (label) { 2579566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, mid)); 258f86f7544SStefano Zampini *mid = *mid - minl + 1; /* MFEM does not like negative markers */ 25977eacf09SStefano Zampini } else *mid = 1; 260044a5661SStefano Zampini if (depth >= 0 && dim != depth) { /* not interpolated, it assumes cell-vertex mesh */ 2611dca8a05SBarry Smith PetscCheck(dim >= 0 && dim <= 3, PETSC_COMM_SELF, PETSC_ERR_SUP, "Dimension %" PetscInt_FMT, dim); 26263a3b9bcSJacob Faibussowitsch PetscCheck(csize <= 8, PETSC_COMM_SELF, PETSC_ERR_SUP, "Found cone size %" PetscInt_FMT " for point %" PetscInt_FMT, csize, p); 26363a3b9bcSJacob Faibussowitsch PetscCheck(depth == 1, PETSC_COMM_SELF, PETSC_ERR_SUP, "Found depth %" PetscInt_FMT " for point %" PetscInt_FMT ". You should interpolate the mesh first", depth, p); 264044a5661SStefano Zampini *cid = mfem_table_cid_unint[dim][csize]; 265044a5661SStefano Zampini } else { 26663a3b9bcSJacob Faibussowitsch PetscCheck(csize <= 6, PETSC_COMM_SELF, PETSC_ERR_SUP, "Cone size %" PetscInt_FMT " for point %" PetscInt_FMT, csize, p); 2671dca8a05SBarry Smith PetscCheck(pdepth >= 0 && pdepth <= 3, PETSC_COMM_SELF, PETSC_ERR_SUP, "Depth %" PetscInt_FMT " for point %" PetscInt_FMT, csize, p); 268044a5661SStefano Zampini *cid = mfem_table_cid[pdepth][csize]; 269044a5661SStefano Zampini } 2708135c375SStefano Zampini PetscFunctionReturn(0); 2718135c375SStefano Zampini } 2728135c375SStefano Zampini 2739371c9d4SSatish Balay static PetscErrorCode DMPlexGetPointMFEMVertexIDs_Internal(DM dm, PetscInt p, PetscSection csec, PetscInt *nv, PetscInt vids[]) { 274cc0d3ed7SStefano Zampini PetscInt dim, sdim, dof = 0, off = 0, i, q, vStart, vEnd, numPoints, *points = NULL; 2758135c375SStefano Zampini 2768135c375SStefano Zampini PetscFunctionBegin; 2779566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 2789566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 279cc0d3ed7SStefano Zampini sdim = dim; 280cc0d3ed7SStefano Zampini if (csec) { 28184f354e3SLisandro Dalcin PetscInt sStart, sEnd; 28284f354e3SLisandro Dalcin 2839566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &sdim)); 2849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(csec, &sStart, &sEnd)); 2859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(csec, vStart, &off)); 286cc0d3ed7SStefano Zampini off = off / sdim; 287*48a46eb9SPierre Jolivet if (p >= sStart && p < sEnd) PetscCall(PetscSectionGetDof(csec, p, &dof)); 28884f354e3SLisandro Dalcin } 289cc0d3ed7SStefano Zampini if (!dof) { 2909566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, p, PETSC_TRUE, &numPoints, &points)); 2918135c375SStefano Zampini for (i = 0, q = 0; i < numPoints * 2; i += 2) 2929371c9d4SSatish Balay if ((points[i] >= vStart) && (points[i] < vEnd)) vids[q++] = points[i] - vStart + off; 2939566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, p, PETSC_TRUE, &numPoints, &points)); 294cc0d3ed7SStefano Zampini } else { 2959566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(csec, p, &off)); 2969566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(csec, p, &dof)); 29796ca5757SLisandro Dalcin for (q = 0; q < dof / sdim; q++) vids[q] = off / sdim + q; 298cc0d3ed7SStefano Zampini } 2998135c375SStefano Zampini *nv = q; 3008135c375SStefano Zampini PetscFunctionReturn(0); 3018135c375SStefano Zampini } 3028135c375SStefano Zampini 3039371c9d4SSatish Balay static PetscErrorCode GLVisCreateFE(PetscFE femIn, char name[32], PetscFE *fem, IS *perm) { 304066ea43fSLisandro Dalcin DM K; 305066ea43fSLisandro Dalcin PetscSpace P; 306066ea43fSLisandro Dalcin PetscDualSpace Q; 307066ea43fSLisandro Dalcin PetscQuadrature q, fq; 308066ea43fSLisandro Dalcin PetscInt dim, deg, dof; 309066ea43fSLisandro Dalcin DMPolytopeType ptype; 310066ea43fSLisandro Dalcin PetscBool isSimplex, isTensor; 311066ea43fSLisandro Dalcin PetscBool continuity = PETSC_FALSE; 312066ea43fSLisandro Dalcin PetscDTNodeType nodeType = PETSCDTNODES_GAUSSJACOBI; 313066ea43fSLisandro Dalcin PetscBool endpoint = PETSC_TRUE; 314066ea43fSLisandro Dalcin MPI_Comm comm; 315066ea43fSLisandro Dalcin 316066ea43fSLisandro Dalcin PetscFunctionBegin; 3179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)femIn, &comm)); 3189566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(femIn, &P)); 3199566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(femIn, &Q)); 3209566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 3219566063dSJacob Faibussowitsch PetscCall(DMGetDimension(K, &dim)); 3229566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(P, °, NULL)); 3239566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(P, &dof)); 3249566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ptype)); 325066ea43fSLisandro Dalcin switch (ptype) { 326066ea43fSLisandro Dalcin case DM_POLYTOPE_QUADRILATERAL: 3279371c9d4SSatish Balay case DM_POLYTOPE_HEXAHEDRON: isSimplex = PETSC_FALSE; break; 3289371c9d4SSatish Balay default: isSimplex = PETSC_TRUE; break; 329066ea43fSLisandro Dalcin } 330066ea43fSLisandro Dalcin isTensor = isSimplex ? PETSC_FALSE : PETSC_TRUE; 3310c2bc6bfSStefano Zampini if (isSimplex) deg = PetscMin(deg, 3); /* Permutation not coded for degree higher than 3 */ 332066ea43fSLisandro Dalcin /* Create space */ 3339566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &P)); 3349566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL)); 3359566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(P, isTensor)); 3369566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(P, dof)); 3379566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(P, dim)); 3389566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(P, deg, PETSC_DETERMINE)); 3399566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(P)); 340066ea43fSLisandro Dalcin /* Create dual space */ 3419566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(comm, &Q)); 3429566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Q, PETSCDUALSPACELAGRANGE)); 3439566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetTensor(Q, isTensor)); 3449566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetContinuity(Q, continuity)); 3459566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetNodeType(Q, nodeType, endpoint, 0)); 3469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(Q, dof)); 3479566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetOrder(Q, deg)); 3489566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, isSimplex), &K)); 3499566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Q, K)); 3509566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 3519566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Q)); 352066ea43fSLisandro Dalcin /* Create quadrature */ 353066ea43fSLisandro Dalcin if (isSimplex) { 3549566063dSJacob Faibussowitsch PetscCall(PetscDTStroudConicalQuadrature(dim, 1, deg + 1, -1, +1, &q)); 3559566063dSJacob Faibussowitsch PetscCall(PetscDTStroudConicalQuadrature(dim - 1, 1, deg + 1, -1, +1, &fq)); 356066ea43fSLisandro Dalcin } else { 3579566063dSJacob Faibussowitsch PetscCall(PetscDTGaussTensorQuadrature(dim, 1, deg + 1, -1, +1, &q)); 3589566063dSJacob Faibussowitsch PetscCall(PetscDTGaussTensorQuadrature(dim - 1, 1, deg + 1, -1, +1, &fq)); 359066ea43fSLisandro Dalcin } 360066ea43fSLisandro Dalcin /* Create finite element */ 3619566063dSJacob Faibussowitsch PetscCall(PetscFECreate(comm, fem)); 36263a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, 32, "L2_T1_%" PetscInt_FMT "D_P%" PetscInt_FMT, dim, deg)); 3639566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*fem, name)); 3649566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*fem, PETSCFEBASIC)); 3659566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*fem, dof)); 3669566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*fem, P)); 3679566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*fem, Q)); 3689566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*fem, q)); 3699566063dSJacob Faibussowitsch PetscCall(PetscFESetFaceQuadrature(*fem, fq)); 3709566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*fem)); 3710c2bc6bfSStefano Zampini 3720c2bc6bfSStefano Zampini /* Both MFEM and PETSc are lexicographic, but PLEX stores the swapped cone */ 3730c2bc6bfSStefano Zampini *perm = NULL; 3740c2bc6bfSStefano Zampini if (isSimplex && dim == 3) { 3750c2bc6bfSStefano Zampini PetscInt celldofs, *pidx; 3760c2bc6bfSStefano Zampini 3770c2bc6bfSStefano Zampini PetscCall(PetscDualSpaceGetDimension(Q, &celldofs)); 3780c2bc6bfSStefano Zampini celldofs /= dof; 3790c2bc6bfSStefano Zampini PetscCall(PetscMalloc1(celldofs, &pidx)); 3800c2bc6bfSStefano Zampini switch (celldofs) { 3810c2bc6bfSStefano Zampini case 4: 3820c2bc6bfSStefano Zampini pidx[0] = 2; 3830c2bc6bfSStefano Zampini pidx[1] = 0; 3840c2bc6bfSStefano Zampini pidx[2] = 1; 3850c2bc6bfSStefano Zampini pidx[3] = 3; 3860c2bc6bfSStefano Zampini break; 3870c2bc6bfSStefano Zampini case 10: 3880c2bc6bfSStefano Zampini pidx[0] = 5; 3890c2bc6bfSStefano Zampini pidx[1] = 3; 3900c2bc6bfSStefano Zampini pidx[2] = 0; 3910c2bc6bfSStefano Zampini pidx[3] = 4; 3920c2bc6bfSStefano Zampini pidx[4] = 1; 3930c2bc6bfSStefano Zampini pidx[5] = 2; 3940c2bc6bfSStefano Zampini pidx[6] = 8; 3950c2bc6bfSStefano Zampini pidx[7] = 6; 3960c2bc6bfSStefano Zampini pidx[8] = 7; 3970c2bc6bfSStefano Zampini pidx[9] = 9; 3980c2bc6bfSStefano Zampini break; 3990c2bc6bfSStefano Zampini case 20: 4000c2bc6bfSStefano Zampini pidx[0] = 9; 4010c2bc6bfSStefano Zampini pidx[1] = 7; 4020c2bc6bfSStefano Zampini pidx[2] = 4; 4030c2bc6bfSStefano Zampini pidx[3] = 0; 4040c2bc6bfSStefano Zampini pidx[4] = 8; 4050c2bc6bfSStefano Zampini pidx[5] = 5; 4060c2bc6bfSStefano Zampini pidx[6] = 1; 4070c2bc6bfSStefano Zampini pidx[7] = 6; 4080c2bc6bfSStefano Zampini pidx[8] = 2; 4090c2bc6bfSStefano Zampini pidx[9] = 3; 4100c2bc6bfSStefano Zampini pidx[10] = 15; 4110c2bc6bfSStefano Zampini pidx[11] = 13; 4120c2bc6bfSStefano Zampini pidx[12] = 10; 4130c2bc6bfSStefano Zampini pidx[13] = 14; 4140c2bc6bfSStefano Zampini pidx[14] = 11; 4150c2bc6bfSStefano Zampini pidx[15] = 12; 4160c2bc6bfSStefano Zampini pidx[16] = 18; 4170c2bc6bfSStefano Zampini pidx[17] = 16; 4180c2bc6bfSStefano Zampini pidx[18] = 17; 4190c2bc6bfSStefano Zampini pidx[19] = 19; 4200c2bc6bfSStefano Zampini break; 4219371c9d4SSatish Balay default: SETERRQ(comm, PETSC_ERR_SUP, "Unhandled degree,dof pair %" PetscInt_FMT ",%" PetscInt_FMT, deg, celldofs); break; 4220c2bc6bfSStefano Zampini } 4230c2bc6bfSStefano Zampini PetscCall(ISCreateBlock(PETSC_COMM_SELF, dof, celldofs, pidx, PETSC_OWN_POINTER, perm)); 4240c2bc6bfSStefano Zampini } 4250c2bc6bfSStefano Zampini 426066ea43fSLisandro Dalcin /* Cleanup */ 4279566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&P)); 4289566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Q)); 4299566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&q)); 4309566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fq)); 431066ea43fSLisandro Dalcin PetscFunctionReturn(0); 432066ea43fSLisandro Dalcin } 433066ea43fSLisandro Dalcin 43477eacf09SStefano Zampini /* 43577eacf09SStefano Zampini ASCII visualization/dump: full support for simplices and tensor product cells. It supports AMR 43677eacf09SStefano Zampini Higher order meshes are also supported 43777eacf09SStefano Zampini */ 4389371c9d4SSatish Balay static PetscErrorCode DMPlexView_GLVis_ASCII(DM dm, PetscViewer viewer) { 4398135c375SStefano Zampini DMLabel label; 4406858538eSMatthew G. Knepley PetscSection coordSection, coordSectionCell, parentSection, hoSection = NULL; 4416858538eSMatthew G. Knepley Vec coordinates, coordinatesCell, hovec; 4428135c375SStefano Zampini const PetscScalar *array; 443f86f7544SStefano Zampini PetscInt bf, p, sdim, dim, depth, novl, minl; 444412e9a14SMatthew G. Knepley PetscInt cStart, cEnd, vStart, vEnd, nvert; 4453924b612SStefano Zampini PetscMPIInt size; 4463e6c54aaSStefano Zampini PetscBool localized, isascii; 44728d58a37SPierre Jolivet PetscBool enable_mfem, enable_boundary, enable_ncmesh, view_ovl = PETSC_FALSE; 4483e6c54aaSStefano Zampini PetscBT pown, vown; 4498135c375SStefano Zampini PetscContainer glvis_container; 4506858538eSMatthew G. Knepley PetscBool cellvertex = PETSC_FALSE, enabled = PETSC_TRUE; 451f86f7544SStefano Zampini PetscBool enable_emark, enable_bmark; 45277eacf09SStefano Zampini const char *fmt; 4537bf4dd16SStefano Zampini char emark[64] = "", bmark[64] = ""; 4548135c375SStefano Zampini 4558135c375SStefano Zampini PetscFunctionBegin; 4568135c375SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4578135c375SStefano Zampini PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 45928b400f6SJacob Faibussowitsch PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer must be of type VIEWERASCII"); 4609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)viewer), &size)); 46108401ef6SPierre Jolivet PetscCheck(size <= 1, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Use single sequential viewers for parallel visualization"); 4629566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 4630c2bc6bfSStefano Zampini PetscCall(DMPlexGetDepth(dm, &depth)); 4648135c375SStefano Zampini 4658135c375SStefano Zampini /* get container: determines if a process visualizes is portion of the data or not */ 4669566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)viewer, "_glvis_info_container", (PetscObject *)&glvis_container)); 46728b400f6SJacob Faibussowitsch PetscCheck(glvis_container, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Missing GLVis container"); 4688135c375SStefano Zampini { 4698135c375SStefano Zampini PetscViewerGLVisInfo glvis_info; 4709566063dSJacob Faibussowitsch PetscCall(PetscContainerGetPointer(glvis_container, (void **)&glvis_info)); 4718135c375SStefano Zampini enabled = glvis_info->enabled; 47277eacf09SStefano Zampini fmt = glvis_info->fmt; 4738135c375SStefano Zampini } 47421414b21SStefano Zampini 4750c2bc6bfSStefano Zampini /* Users can attach a coordinate vector to the DM in case they have a higher-order mesh */ 4769566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "_glvis_mesh_coords", (PetscObject *)&hovec)); 4779566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)hovec)); 478066ea43fSLisandro Dalcin if (!hovec) { 479066ea43fSLisandro Dalcin DM cdm; 480066ea43fSLisandro Dalcin PetscFE disc; 481066ea43fSLisandro Dalcin PetscClassId classid; 482066ea43fSLisandro Dalcin 4839566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dm, &cdm)); 4849566063dSJacob Faibussowitsch PetscCall(DMGetField(cdm, 0, NULL, (PetscObject *)&disc)); 4859566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId((PetscObject)disc, &classid)); 486066ea43fSLisandro Dalcin if (classid == PETSCFE_CLASSID) { 487066ea43fSLisandro Dalcin DM hocdm; 488066ea43fSLisandro Dalcin PetscFE hodisc; 489066ea43fSLisandro Dalcin Vec vec; 490066ea43fSLisandro Dalcin Mat mat; 491066ea43fSLisandro Dalcin char name[32], fec_type[64]; 4920c2bc6bfSStefano Zampini IS perm = NULL; 493066ea43fSLisandro Dalcin 4940c2bc6bfSStefano Zampini PetscCall(GLVisCreateFE(disc, name, &hodisc, &perm)); 4959566063dSJacob Faibussowitsch PetscCall(DMClone(cdm, &hocdm)); 4969566063dSJacob Faibussowitsch PetscCall(DMSetField(hocdm, 0, NULL, (PetscObject)hodisc)); 4979566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&hodisc)); 4989566063dSJacob Faibussowitsch PetscCall(DMCreateDS(hocdm)); 499066ea43fSLisandro Dalcin 5009566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &vec)); 5019566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(hocdm, &hovec)); 5029566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(cdm, hocdm, &mat, NULL)); 5039566063dSJacob Faibussowitsch PetscCall(MatInterpolate(mat, vec, hovec)); 5049566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat)); 5050c2bc6bfSStefano Zampini PetscCall(DMGetLocalSection(hocdm, &hoSection)); 5060c2bc6bfSStefano Zampini PetscCall(PetscSectionSetClosurePermutation(hoSection, (PetscObject)hocdm, depth, perm)); 5070c2bc6bfSStefano Zampini PetscCall(ISDestroy(&perm)); 5089566063dSJacob Faibussowitsch PetscCall(DMDestroy(&hocdm)); 5099566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(fec_type, sizeof(fec_type), "FiniteElementCollection: %s", name)); 5109566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)hovec, fec_type)); 511066ea43fSLisandro Dalcin } 512066ea43fSLisandro Dalcin } 51321414b21SStefano Zampini 5149566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 5159566063dSJacob Faibussowitsch PetscCall(DMPlexGetGhostCellStratum(dm, &p, NULL)); 516c3c203b2SStefano Zampini if (p >= 0) cEnd = p; 5179566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 5189566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocalized(dm, &localized)); 5199566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 5209566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &sdim)); 5219566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 52208401ef6SPierre Jolivet PetscCheck(coordinates || hovec, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing local coordinates vector"); 5238135c375SStefano Zampini 5248135c375SStefano Zampini /* 5258135c375SStefano Zampini a couple of sections of the mesh specification are disabled 5263e96840aSStefano Zampini - boundary: the boundary is not needed for proper mesh visualization unless we want to visualize boundary attributes or we have high-order coordinates in 3D (topologically) 52777eacf09SStefano Zampini - vertex_parents: used for non-conforming meshes only when we want to use MFEM as a discretization package 5283e6c54aaSStefano Zampini and be able to derefine the mesh (MFEM does not currently have to ability to read ncmeshes in parallel) 5298135c375SStefano Zampini */ 5303e96840aSStefano Zampini enable_boundary = PETSC_FALSE; 5318135c375SStefano Zampini enable_ncmesh = PETSC_FALSE; 5323e6c54aaSStefano Zampini enable_mfem = PETSC_FALSE; 533f86f7544SStefano Zampini enable_emark = PETSC_FALSE; 534f86f7544SStefano Zampini enable_bmark = PETSC_FALSE; 5357bf4dd16SStefano Zampini /* I'm tired of problems with negative values in the markers, disable them */ 536d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->prefix, "GLVis PetscViewer DMPlex Options", "PetscViewer"); 5379566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-viewer_glvis_dm_plex_enable_boundary", "Enable boundary section in mesh representation", NULL, enable_boundary, &enable_boundary, NULL)); 5389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-viewer_glvis_dm_plex_enable_ncmesh", "Enable vertex_parents section in mesh representation (allows derefinement)", NULL, enable_ncmesh, &enable_ncmesh, NULL)); 5399566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-viewer_glvis_dm_plex_enable_mfem", "Dump a mesh that can be used with MFEM's FiniteElementSpaces", NULL, enable_mfem, &enable_mfem, NULL)); 5409566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-viewer_glvis_dm_plex_overlap", "Include overlap region in local meshes", NULL, view_ovl, &view_ovl, NULL)); 5419566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-viewer_glvis_dm_plex_emarker", "String for the material id label", NULL, emark, emark, sizeof(emark), &enable_emark)); 5429566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-viewer_glvis_dm_plex_bmarker", "String for the boundary id label", NULL, bmark, bmark, sizeof(bmark), &enable_bmark)); 543d0609cedSBarry Smith PetscOptionsEnd(); 544f86f7544SStefano Zampini if (enable_bmark) enable_boundary = PETSC_TRUE; 545f86f7544SStefano Zampini 5469566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 5471dca8a05SBarry Smith PetscCheck(!enable_ncmesh || size == 1, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Not supported in parallel"); 5489371c9d4SSatish Balay PetscCheck(!enable_boundary || depth < 0 || dim == depth, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, 5499371c9d4SSatish Balay "Mesh must be interpolated. " 5507e1aca4eSStefano Zampini "Alternatively, run with -viewer_glvis_dm_plex_enable_boundary 0"); 5519371c9d4SSatish Balay PetscCheck(!enable_ncmesh || depth < 0 || dim == depth, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, 5529371c9d4SSatish Balay "Mesh must be interpolated. " 5537e1aca4eSStefano Zampini "Alternatively, run with -viewer_glvis_dm_plex_enable_ncmesh 0"); 554044a5661SStefano Zampini if (depth >= 0 && dim != depth) { /* not interpolated, it assumes cell-vertex mesh */ 55563a3b9bcSJacob Faibussowitsch PetscCheck(depth == 1, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported depth %" PetscInt_FMT ". You should interpolate the mesh first", depth); 556044a5661SStefano Zampini cellvertex = PETSC_TRUE; 557044a5661SStefano Zampini } 5588135c375SStefano Zampini 5598135c375SStefano Zampini /* Identify possible cells in the overlap */ 5608135c375SStefano Zampini novl = 0; 5618135c375SStefano Zampini pown = NULL; 5623924b612SStefano Zampini if (size > 1) { 5633e6c54aaSStefano Zampini IS globalNum = NULL; 5643e6c54aaSStefano Zampini const PetscInt *gNum; 5653e6c54aaSStefano Zampini PetscBool ovl = PETSC_FALSE; 5663e6c54aaSStefano Zampini 5679566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "_glvis_plex_gnum", (PetscObject *)&globalNum)); 568b135d7daSStefano Zampini if (!globalNum) { 56928d58a37SPierre Jolivet if (view_ovl) { 5709566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PetscObjectComm((PetscObject)dm), cEnd - cStart, 0, 1, &globalNum)); 57128d58a37SPierre Jolivet } else { 5729566063dSJacob Faibussowitsch PetscCall(DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &globalNum)); 57328d58a37SPierre Jolivet } 5749566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)dm, "_glvis_plex_gnum", (PetscObject)globalNum)); 5759566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)globalNum)); 576b135d7daSStefano Zampini } 5779566063dSJacob Faibussowitsch PetscCall(ISGetIndices(globalNum, &gNum)); 5788135c375SStefano Zampini for (p = cStart; p < cEnd; p++) { 5798135c375SStefano Zampini if (gNum[p - cStart] < 0) { 5808135c375SStefano Zampini ovl = PETSC_TRUE; 5818135c375SStefano Zampini novl++; 5828135c375SStefano Zampini } 5838135c375SStefano Zampini } 5848135c375SStefano Zampini if (ovl) { 5858135c375SStefano Zampini /* it may happen that pown get not destroyed, if the user closes the window while this function is running. 5868135c375SStefano Zampini TODO: garbage collector? attach pown to dm? */ 5879566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(cEnd - cStart, &pown)); 5883e6c54aaSStefano Zampini for (p = cStart; p < cEnd; p++) { 5893e6c54aaSStefano Zampini if (gNum[p - cStart] < 0) continue; 590*48a46eb9SPierre Jolivet else PetscCall(PetscBTSet(pown, p - cStart)); 5918135c375SStefano Zampini } 5923e6c54aaSStefano Zampini } 5939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(globalNum, &gNum)); 5943e6c54aaSStefano Zampini } 5958135c375SStefano Zampini 5961d4815f0SStefano Zampini /* vertex_parents (Non-conforming meshes) */ 5971d4815f0SStefano Zampini parentSection = NULL; 5981d4815f0SStefano Zampini if (enable_ncmesh) { 5999566063dSJacob Faibussowitsch PetscCall(DMPlexGetTree(dm, &parentSection, NULL, NULL, NULL, NULL)); 6001d4815f0SStefano Zampini enable_ncmesh = (PetscBool)(enable_ncmesh && parentSection); 6011d4815f0SStefano Zampini } 6023e6c54aaSStefano Zampini /* return if this process is disabled */ 6038135c375SStefano Zampini if (!enabled) { 6049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MFEM mesh %s\n", enable_ncmesh ? "v1.1" : "v1.0")); 6059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\ndimension\n")); 60663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", dim)); 6079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nelements\n")); 60863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "0\n")); 6099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nboundary\n")); 61063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "0\n")); 6119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nvertices\n")); 61263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "0\n")); 61363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", sdim)); 6149566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&pown)); 6159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&hovec)); 6168135c375SStefano Zampini PetscFunctionReturn(0); 6178135c375SStefano Zampini } 6188135c375SStefano Zampini 6193e6c54aaSStefano Zampini if (enable_mfem) { 6206858538eSMatthew G. Knepley if (localized && !hovec) { /* we need to generate a vector of L2 coordinates, as this is how MFEM handles periodic meshes */ 6213e6c54aaSStefano Zampini PetscInt vpc = 0; 6223e6c54aaSStefano Zampini char fec[64]; 62396ca5757SLisandro Dalcin PetscInt vids[8] = {0, 1, 2, 3, 4, 5, 6, 7}; 62496ca5757SLisandro Dalcin PetscInt hexv[8] = {0, 1, 3, 2, 4, 5, 7, 6}, tetv[4] = {0, 1, 2, 3}; 62596ca5757SLisandro Dalcin PetscInt quadv[8] = {0, 1, 3, 2}, triv[3] = {0, 1, 2}; 62696ca5757SLisandro Dalcin PetscInt *dof = NULL; 6273e6c54aaSStefano Zampini PetscScalar *array, *ptr; 6283e6c54aaSStefano Zampini 62963a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(fec, sizeof(fec), "FiniteElementCollection: L2_T1_%" PetscInt_FMT "D_P1", dim)); 6303e6c54aaSStefano Zampini if (cEnd - cStart) { 6313e6c54aaSStefano Zampini PetscInt fpc; 6323e6c54aaSStefano Zampini 6339566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cStart, &fpc)); 6343e6c54aaSStefano Zampini switch (dim) { 6353e6c54aaSStefano Zampini case 1: 6363e6c54aaSStefano Zampini vpc = 2; 6373e6c54aaSStefano Zampini dof = hexv; 6383e6c54aaSStefano Zampini break; 6393e6c54aaSStefano Zampini case 2: 6403e6c54aaSStefano Zampini switch (fpc) { 6413e6c54aaSStefano Zampini case 3: 6423e6c54aaSStefano Zampini vpc = 3; 643044a5661SStefano Zampini dof = triv; 6443e6c54aaSStefano Zampini break; 6453e6c54aaSStefano Zampini case 4: 6463e6c54aaSStefano Zampini vpc = 4; 647044a5661SStefano Zampini dof = quadv; 6483e6c54aaSStefano Zampini break; 6499371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled case: faces per cell %" PetscInt_FMT, fpc); 6503e6c54aaSStefano Zampini } 6513e6c54aaSStefano Zampini break; 6523e6c54aaSStefano Zampini case 3: 6533e6c54aaSStefano Zampini switch (fpc) { 654044a5661SStefano Zampini case 4: /* TODO: still need to understand L2 ordering for tets */ 6553e6c54aaSStefano Zampini vpc = 4; 656044a5661SStefano Zampini dof = tetv; 657044a5661SStefano Zampini SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled tethraedral case"); 6583e6c54aaSStefano Zampini case 6: 65963a3b9bcSJacob Faibussowitsch PetscCheck(!cellvertex, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled case: vertices per cell %" PetscInt_FMT, fpc); 660044a5661SStefano Zampini vpc = 8; 661044a5661SStefano Zampini dof = hexv; 662044a5661SStefano Zampini break; 663044a5661SStefano Zampini case 8: 66463a3b9bcSJacob Faibussowitsch PetscCheck(cellvertex, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled case: faces per cell %" PetscInt_FMT, fpc); 6653e6c54aaSStefano Zampini vpc = 8; 6663e6c54aaSStefano Zampini dof = hexv; 6673e6c54aaSStefano Zampini break; 6689371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled case: faces per cell %" PetscInt_FMT, fpc); 6693e6c54aaSStefano Zampini } 6703e6c54aaSStefano Zampini break; 6719371c9d4SSatish Balay default: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unhandled dim"); 6723e6c54aaSStefano Zampini } 6739566063dSJacob Faibussowitsch PetscCall(DMPlexReorderCell(dm, cStart, vids)); 6743e6c54aaSStefano Zampini } 67528b400f6SJacob Faibussowitsch PetscCheck(dof, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Missing dofs"); 6769566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, (cEnd - cStart - novl) * vpc * sdim, &hovec)); 6779566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)hovec, fec)); 6789566063dSJacob Faibussowitsch PetscCall(VecGetArray(hovec, &array)); 6793e6c54aaSStefano Zampini ptr = array; 6803e6c54aaSStefano Zampini for (p = cStart; p < cEnd; p++) { 6813e6c54aaSStefano Zampini PetscInt csize, v, d; 6823e6c54aaSStefano Zampini PetscScalar *vals = NULL; 6833e6c54aaSStefano Zampini 6843e6c54aaSStefano Zampini if (PetscUnlikely(pown && !PetscBTLookup(pown, p - cStart))) continue; 6859566063dSJacob Faibussowitsch PetscCall(DMPlexVecGetClosure(dm, coordSection, coordinates, p, &csize, &vals)); 6861dca8a05SBarry Smith PetscCheck(csize == vpc * sdim || csize == vpc * sdim * 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported closure size %" PetscInt_FMT " (vpc %" PetscInt_FMT ", sdim %" PetscInt_FMT ")", csize, vpc, sdim); 6873e6c54aaSStefano Zampini for (v = 0; v < vpc; v++) { 6889371c9d4SSatish Balay for (d = 0; d < sdim; d++) { ptr[sdim * dof[v] + d] = vals[sdim * vids[v] + d]; } 6893e6c54aaSStefano Zampini } 6903e6c54aaSStefano Zampini ptr += vpc * sdim; 6919566063dSJacob Faibussowitsch PetscCall(DMPlexVecRestoreClosure(dm, coordSection, coordinates, p, &csize, &vals)); 6923e6c54aaSStefano Zampini } 6939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(hovec, &array)); 6943e6c54aaSStefano Zampini } 6953e6c54aaSStefano Zampini } 6963e96840aSStefano Zampini /* if we have high-order coordinates in 3D, we need to specify the boundary */ 6973e96840aSStefano Zampini if (hovec && dim == 3) enable_boundary = PETSC_TRUE; 6983e6c54aaSStefano Zampini 6998135c375SStefano Zampini /* header */ 7009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MFEM mesh %s\n", enable_ncmesh ? "v1.1" : "v1.0")); 7018135c375SStefano Zampini 7028135c375SStefano Zampini /* topological dimension */ 7039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\ndimension\n")); 70463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", dim)); 7058135c375SStefano Zampini 7068135c375SStefano Zampini /* elements */ 707f86f7544SStefano Zampini minl = 1; 708f86f7544SStefano Zampini label = NULL; 709f86f7544SStefano Zampini if (enable_emark) { 710f86f7544SStefano Zampini PetscInt lminl = PETSC_MAX_INT; 711f86f7544SStefano Zampini 7129566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, emark, &label)); 713f86f7544SStefano Zampini if (label) { 714f86f7544SStefano Zampini IS vals; 715f86f7544SStefano Zampini PetscInt ldef; 716f86f7544SStefano Zampini 7179566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &ldef)); 7189566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vals)); 7199566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(vals, &lminl, NULL)); 7209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vals)); 721f86f7544SStefano Zampini lminl = PetscMin(ldef, lminl); 722f86f7544SStefano Zampini } 7231c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&lminl, &minl, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm))); 724f86f7544SStefano Zampini if (minl == PETSC_MAX_INT) minl = 1; 725f86f7544SStefano Zampini } 7269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nelements\n")); 72763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", cEnd - cStart - novl)); 7288135c375SStefano Zampini for (p = cStart; p < cEnd; p++) { 72996ca5757SLisandro Dalcin PetscInt vids[8]; 73011a4995dSStefano Zampini PetscInt i, nv = 0, cid = -1, mid = 1; 7318135c375SStefano Zampini 7323e6c54aaSStefano Zampini if (PetscUnlikely(pown && !PetscBTLookup(pown, p - cStart))) continue; 7339566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointMFEMCellID_Internal(dm, label, minl, p, &mid, &cid)); 7349566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointMFEMVertexIDs_Internal(dm, p, (localized && !hovec) ? coordSection : NULL, &nv, vids)); 7359566063dSJacob Faibussowitsch PetscCall(DMPlexReorderCell(dm, p, vids)); 73663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " %" PetscInt_FMT, mid, cid)); 737*48a46eb9SPierre Jolivet for (i = 0; i < nv; i++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, vids[i])); 7389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 7398135c375SStefano Zampini } 7408135c375SStefano Zampini 741cc0d3ed7SStefano Zampini /* boundary */ 7429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nboundary\n")); 743cc0d3ed7SStefano Zampini if (!enable_boundary) { 74463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "0\n")); 745cc0d3ed7SStefano Zampini } else { 74677eacf09SStefano Zampini DMLabel perLabel; 74777eacf09SStefano Zampini PetscBT bfaces; 748b135d7daSStefano Zampini PetscInt fStart, fEnd, *fcells; 749cc0d3ed7SStefano Zampini 7509566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd)); 7519566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(fEnd - fStart, &bfaces)); 7529566063dSJacob Faibussowitsch PetscCall(DMPlexGetMaxSizes(dm, NULL, &p)); 7539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(p, &fcells)); 7549566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "glvis_periodic_cut", &perLabel)); 7556858538eSMatthew G. Knepley if (!perLabel && localized) { /* this periodic cut can be moved up to DMPlex setup */ 7569566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, "glvis_periodic_cut")); 7579566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "glvis_periodic_cut", &perLabel)); 7589566063dSJacob Faibussowitsch PetscCall(DMLabelSetDefaultValue(perLabel, 1)); 7596858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateSection(dm, &coordSectionCell)); 7606858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coordinatesCell)); 76177eacf09SStefano Zampini for (p = cStart; p < cEnd; p++) { 762c3c203b2SStefano Zampini DMPolytopeType cellType; 763c3c203b2SStefano Zampini PetscInt dof; 764b135d7daSStefano Zampini 7659566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, p, &cellType)); 7666858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(coordSectionCell, p, &dof)); 76777eacf09SStefano Zampini if (dof) { 7686858538eSMatthew G. Knepley PetscInt uvpc, v, csize, csizeCell, cellClosureSize, *cellClosure = NULL, *vidxs = NULL; 7696858538eSMatthew G. Knepley PetscScalar *vals = NULL, *valsCell = NULL; 770c3c203b2SStefano Zampini 771c3c203b2SStefano Zampini uvpc = DMPolytopeTypeGetNumVertices(cellType); 77263a3b9bcSJacob Faibussowitsch PetscCheck(dof % sdim == 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Incompatible number of cell dofs %" PetscInt_FMT " and space dimension %" PetscInt_FMT, dof, sdim); 7739566063dSJacob Faibussowitsch PetscCall(DMPlexVecGetClosure(dm, coordSection, coordinates, p, &csize, &vals)); 7746858538eSMatthew G. Knepley PetscCall(DMPlexVecGetClosure(dm, coordSectionCell, coordinatesCell, p, &csizeCell, &valsCell)); 7756858538eSMatthew G. Knepley PetscCheck(csize == csizeCell, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell %" PetscInt_FMT " has invalid localized coordinates", p); 7769566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, p, PETSC_TRUE, &cellClosureSize, &cellClosure)); 77777eacf09SStefano Zampini for (v = 0; v < cellClosureSize; v++) 77877eacf09SStefano Zampini if (cellClosure[2 * v] >= vStart && cellClosure[2 * v] < vEnd) { 77977eacf09SStefano Zampini vidxs = cellClosure + 2 * v; 78077eacf09SStefano Zampini break; 78177eacf09SStefano Zampini } 78228b400f6SJacob Faibussowitsch PetscCheck(vidxs, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing vertices"); 783b135d7daSStefano Zampini for (v = 0; v < uvpc; v++) { 78477eacf09SStefano Zampini PetscInt s; 785044a5661SStefano Zampini 78677eacf09SStefano Zampini for (s = 0; s < sdim; s++) { 787*48a46eb9SPierre Jolivet if (PetscAbsScalar(vals[v * sdim + s] - valsCell[v * sdim + s]) > PETSC_MACHINE_EPSILON) PetscCall(DMLabelSetValue(perLabel, vidxs[2 * v], 2)); 78877eacf09SStefano Zampini } 78977eacf09SStefano Zampini } 7909566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, p, PETSC_TRUE, &cellClosureSize, &cellClosure)); 7919566063dSJacob Faibussowitsch PetscCall(DMPlexVecRestoreClosure(dm, coordSection, coordinates, p, &csize, &vals)); 7926858538eSMatthew G. Knepley PetscCall(DMPlexVecRestoreClosure(dm, coordSectionCell, coordinatesCell, p, &csizeCell, &valsCell)); 79377eacf09SStefano Zampini } 79477eacf09SStefano Zampini } 79577eacf09SStefano Zampini if (dim > 1) { 796b135d7daSStefano Zampini PetscInt eEnd, eStart; 797044a5661SStefano Zampini 7989566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd)); 79977eacf09SStefano Zampini for (p = eStart; p < eEnd; p++) { 80077eacf09SStefano Zampini const PetscInt *cone; 80177eacf09SStefano Zampini PetscInt coneSize, i; 80277eacf09SStefano Zampini PetscBool ispe = PETSC_TRUE; 80377eacf09SStefano Zampini 8049566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, p, &cone)); 8059566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, p, &coneSize)); 80677eacf09SStefano Zampini for (i = 0; i < coneSize; i++) { 80777eacf09SStefano Zampini PetscInt v; 80877eacf09SStefano Zampini 8099566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(perLabel, cone[i], &v)); 81077eacf09SStefano Zampini ispe = (PetscBool)(ispe && (v == 2)); 81177eacf09SStefano Zampini } 81277eacf09SStefano Zampini if (ispe && coneSize) { 8133e96840aSStefano Zampini PetscInt ch, numChildren; 8143e96840aSStefano Zampini const PetscInt *children; 8153e96840aSStefano Zampini 8169566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(perLabel, p, 2)); 8179566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeChildren(dm, p, &numChildren, &children)); 818*48a46eb9SPierre Jolivet for (ch = 0; ch < numChildren; ch++) PetscCall(DMLabelSetValue(perLabel, children[ch], 2)); 81977eacf09SStefano Zampini } 82077eacf09SStefano Zampini } 82177eacf09SStefano Zampini if (dim > 2) { 82277eacf09SStefano Zampini for (p = fStart; p < fEnd; p++) { 82377eacf09SStefano Zampini const PetscInt *cone; 82477eacf09SStefano Zampini PetscInt coneSize, i; 82577eacf09SStefano Zampini PetscBool ispe = PETSC_TRUE; 82677eacf09SStefano Zampini 8279566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, p, &cone)); 8289566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, p, &coneSize)); 82977eacf09SStefano Zampini for (i = 0; i < coneSize; i++) { 83077eacf09SStefano Zampini PetscInt v; 83177eacf09SStefano Zampini 8329566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(perLabel, cone[i], &v)); 83377eacf09SStefano Zampini ispe = (PetscBool)(ispe && (v == 2)); 83477eacf09SStefano Zampini } 83577eacf09SStefano Zampini if (ispe && coneSize) { 8363e96840aSStefano Zampini PetscInt ch, numChildren; 8373e96840aSStefano Zampini const PetscInt *children; 8383e96840aSStefano Zampini 8399566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(perLabel, p, 2)); 8409566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeChildren(dm, p, &numChildren, &children)); 841*48a46eb9SPierre Jolivet for (ch = 0; ch < numChildren; ch++) PetscCall(DMLabelSetValue(perLabel, children[ch], 2)); 84277eacf09SStefano Zampini } 84377eacf09SStefano Zampini } 84477eacf09SStefano Zampini } 84577eacf09SStefano Zampini } 84677eacf09SStefano Zampini } 84777eacf09SStefano Zampini for (p = fStart; p < fEnd; p++) { 84877eacf09SStefano Zampini const PetscInt *support; 8498135c375SStefano Zampini PetscInt supportSize; 85077eacf09SStefano Zampini PetscBool isbf = PETSC_FALSE; 8518135c375SStefano Zampini 8529566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dm, p, &supportSize)); 8533e6c54aaSStefano Zampini if (pown) { 8548135c375SStefano Zampini PetscBool has_owned = PETSC_FALSE, has_ghost = PETSC_FALSE; 85577eacf09SStefano Zampini PetscInt i; 85677eacf09SStefano Zampini 8579566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, p, &support)); 85877eacf09SStefano Zampini for (i = 0; i < supportSize; i++) { 85977eacf09SStefano Zampini if (PetscLikely(PetscBTLookup(pown, support[i] - cStart))) has_owned = PETSC_TRUE; 86077eacf09SStefano Zampini else has_ghost = PETSC_TRUE; 86177eacf09SStefano Zampini } 86277eacf09SStefano Zampini isbf = (PetscBool)((supportSize == 1 && has_owned) || (supportSize > 1 && has_owned && has_ghost)); 86377eacf09SStefano Zampini } else { 86477eacf09SStefano Zampini isbf = (PetscBool)(supportSize == 1); 86577eacf09SStefano Zampini } 86677eacf09SStefano Zampini if (!isbf && perLabel) { 86777eacf09SStefano Zampini const PetscInt *cone; 86877eacf09SStefano Zampini PetscInt coneSize, i; 86977eacf09SStefano Zampini 8709566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, p, &cone)); 8719566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, p, &coneSize)); 87277eacf09SStefano Zampini isbf = PETSC_TRUE; 87377eacf09SStefano Zampini for (i = 0; i < coneSize; i++) { 87477eacf09SStefano Zampini PetscInt v, d; 87577eacf09SStefano Zampini 8769566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(perLabel, cone[i], &v)); 8779566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(perLabel, &d)); 87877eacf09SStefano Zampini isbf = (PetscBool)(isbf && v != d); 87977eacf09SStefano Zampini } 88077eacf09SStefano Zampini } 8811baa6e33SBarry Smith if (isbf) PetscCall(PetscBTSet(bfaces, p - fStart)); 88277eacf09SStefano Zampini } 88377eacf09SStefano Zampini /* count boundary faces */ 88477eacf09SStefano Zampini for (p = fStart, bf = 0; p < fEnd; p++) { 88577eacf09SStefano Zampini if (PetscUnlikely(PetscBTLookup(bfaces, p - fStart))) { 88677eacf09SStefano Zampini const PetscInt *support; 88777eacf09SStefano Zampini PetscInt supportSize, c; 8888135c375SStefano Zampini 8899566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dm, p, &supportSize)); 8909566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, p, &support)); 89177eacf09SStefano Zampini for (c = 0; c < supportSize; c++) { 8923e96840aSStefano Zampini const PetscInt *cone; 893b135d7daSStefano Zampini PetscInt cell, cl, coneSize; 8943e96840aSStefano Zampini 8953e96840aSStefano Zampini cell = support[c]; 8963e96840aSStefano Zampini if (pown && PetscUnlikely(!PetscBTLookup(pown, cell - cStart))) continue; 8979566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &cone)); 8989566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &coneSize)); 899b135d7daSStefano Zampini for (cl = 0; cl < coneSize; cl++) { 9003e96840aSStefano Zampini if (cone[cl] == p) { 9013e96840aSStefano Zampini bf += 1; 9023e96840aSStefano Zampini break; 9038135c375SStefano Zampini } 90477eacf09SStefano Zampini } 9053e96840aSStefano Zampini } 9068135c375SStefano Zampini } 9078135c375SStefano Zampini } 908f86f7544SStefano Zampini minl = 1; 909f86f7544SStefano Zampini label = NULL; 910f86f7544SStefano Zampini if (enable_bmark) { 911f86f7544SStefano Zampini PetscInt lminl = PETSC_MAX_INT; 912f86f7544SStefano Zampini 9139566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, bmark, &label)); 914f86f7544SStefano Zampini if (label) { 915f86f7544SStefano Zampini IS vals; 916f86f7544SStefano Zampini PetscInt ldef; 917f86f7544SStefano Zampini 9189566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &ldef)); 9199566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vals)); 9209566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(vals, &lminl, NULL)); 9219566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vals)); 922f86f7544SStefano Zampini lminl = PetscMin(ldef, lminl); 923f86f7544SStefano Zampini } 9241c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&lminl, &minl, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm))); 925f86f7544SStefano Zampini if (minl == PETSC_MAX_INT) minl = 1; 926f86f7544SStefano Zampini } 92763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", bf)); 9288135c375SStefano Zampini for (p = fStart; p < fEnd; p++) { 92977eacf09SStefano Zampini if (PetscUnlikely(PetscBTLookup(bfaces, p - fStart))) { 9308135c375SStefano Zampini const PetscInt *support; 93177eacf09SStefano Zampini PetscInt supportSize, c, nc = 0; 9328135c375SStefano Zampini 9339566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dm, p, &supportSize)); 9349566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, p, &support)); 9353e6c54aaSStefano Zampini if (pown) { 93677eacf09SStefano Zampini for (c = 0; c < supportSize; c++) { 9379371c9d4SSatish Balay if (PetscLikely(PetscBTLookup(pown, support[c] - cStart))) { fcells[nc++] = support[c]; } 9388135c375SStefano Zampini } 9399371c9d4SSatish Balay } else 9409371c9d4SSatish Balay for (c = 0; c < supportSize; c++) fcells[nc++] = support[c]; 94177eacf09SStefano Zampini for (c = 0; c < nc; c++) { 942c3c203b2SStefano Zampini const DMPolytopeType *faceTypes; 943c3c203b2SStefano Zampini DMPolytopeType cellType; 944c3c203b2SStefano Zampini const PetscInt *faceSizes, *cone; 945c3c203b2SStefano Zampini PetscInt vids[8], *faces, st, i, coneSize, cell, cl, nv, cid = -1, mid = -1; 9468135c375SStefano Zampini 94777eacf09SStefano Zampini cell = fcells[c]; 9489566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &cone)); 9499566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &coneSize)); 950b135d7daSStefano Zampini for (cl = 0; cl < coneSize; cl++) 9519371c9d4SSatish Balay if (cone[cl] == p) break; 952b135d7daSStefano Zampini if (cl == coneSize) continue; 9538135c375SStefano Zampini 95477eacf09SStefano Zampini /* face material id and type */ 9559566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointMFEMCellID_Internal(dm, label, minl, p, &mid, &cid)); 95663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " %" PetscInt_FMT, mid, cid)); 95777eacf09SStefano Zampini /* vertex ids */ 9589566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cell, &cellType)); 9599566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointMFEMVertexIDs_Internal(dm, cell, (localized && !hovec) ? coordSection : NULL, &nv, vids)); 9609566063dSJacob Faibussowitsch PetscCall(DMPlexGetRawFaces_Internal(dm, cellType, vids, NULL, &faceTypes, &faceSizes, (const PetscInt **)&faces)); 961c3c203b2SStefano Zampini st = 0; 962c3c203b2SStefano Zampini for (i = 0; i < cl; i++) st += faceSizes[i]; 9639566063dSJacob Faibussowitsch PetscCall(DMPlexInvertCell(faceTypes[cl], faces + st)); 964*48a46eb9SPierre Jolivet for (i = 0; i < faceSizes[cl]; i++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, faces[st + i])); 9659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 9669566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreRawFaces_Internal(dm, cellType, vids, NULL, &faceTypes, &faceSizes, (const PetscInt **)&faces)); 9673e96840aSStefano Zampini bf -= 1; 96877eacf09SStefano Zampini } 9698135c375SStefano Zampini } 9708135c375SStefano Zampini } 97163a3b9bcSJacob Faibussowitsch PetscCheck(!bf, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Remaining boundary faces %" PetscInt_FMT, bf); 9729566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&bfaces)); 9739566063dSJacob Faibussowitsch PetscCall(PetscFree(fcells)); 9748135c375SStefano Zampini } 9758135c375SStefano Zampini 9768135c375SStefano Zampini /* mark owned vertices */ 9773e6c54aaSStefano Zampini vown = NULL; 9783e6c54aaSStefano Zampini if (pown) { 9799566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(vEnd - vStart, &vown)); 9808135c375SStefano Zampini for (p = cStart; p < cEnd; p++) { 9818135c375SStefano Zampini PetscInt i, closureSize, *closure = NULL; 9828135c375SStefano Zampini 9833e6c54aaSStefano Zampini if (PetscUnlikely(!PetscBTLookup(pown, p - cStart))) continue; 9849566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, p, PETSC_TRUE, &closureSize, &closure)); 9858135c375SStefano Zampini for (i = 0; i < closureSize; i++) { 9868135c375SStefano Zampini const PetscInt pp = closure[2 * i]; 9878135c375SStefano Zampini 988*48a46eb9SPierre Jolivet if (pp >= vStart && pp < vEnd) PetscCall(PetscBTSet(vown, pp - vStart)); 9898135c375SStefano Zampini } 9909566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, p, PETSC_TRUE, &closureSize, &closure)); 9918135c375SStefano Zampini } 9928135c375SStefano Zampini } 9938135c375SStefano Zampini 9948135c375SStefano Zampini if (parentSection) { 9958135c375SStefano Zampini PetscInt vp, gvp; 9968135c375SStefano Zampini 9978135c375SStefano Zampini for (vp = 0, p = vStart; p < vEnd; p++) { 9988135c375SStefano Zampini DMLabel dlabel; 9998135c375SStefano Zampini PetscInt parent, depth; 10008135c375SStefano Zampini 10013e6c54aaSStefano Zampini if (PetscUnlikely(vown && !PetscBTLookup(vown, p - vStart))) continue; 10029566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &dlabel)); 10039566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dlabel, p, &depth)); 10049566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeParent(dm, p, &parent, NULL)); 10058135c375SStefano Zampini if (parent != p) vp++; 10068135c375SStefano Zampini } 10071c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&vp, &gvp, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)dm))); 10088135c375SStefano Zampini if (gvp) { 10098135c375SStefano Zampini PetscInt maxsupp; 10108135c375SStefano Zampini PetscBool *skip = NULL; 10118135c375SStefano Zampini 10129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nvertex_parents\n")); 101363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", vp)); 10149566063dSJacob Faibussowitsch PetscCall(DMPlexGetMaxSizes(dm, NULL, &maxsupp)); 10159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(maxsupp, &skip)); 10168135c375SStefano Zampini for (p = vStart; p < vEnd; p++) { 10178135c375SStefano Zampini DMLabel dlabel; 10188135c375SStefano Zampini PetscInt parent; 10198135c375SStefano Zampini 10203e6c54aaSStefano Zampini if (PetscUnlikely(vown && !PetscBTLookup(vown, p - vStart))) continue; 10219566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &dlabel)); 10229566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeParent(dm, p, &parent, NULL)); 10238135c375SStefano Zampini if (parent != p) { 102496ca5757SLisandro Dalcin PetscInt vids[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* silent overzealous clang static analyzer */ 10253924b612SStefano Zampini PetscInt i, nv, ssize, n, numChildren, depth = -1; 10268135c375SStefano Zampini const PetscInt *children; 10273924b612SStefano Zampini 10289566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, parent, &ssize)); 10293924b612SStefano Zampini switch (ssize) { 10308135c375SStefano Zampini case 2: /* edge */ 10318135c375SStefano Zampini nv = 0; 10329566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointMFEMVertexIDs_Internal(dm, parent, localized ? coordSection : NULL, &nv, vids)); 103363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, p - vStart)); 1034*48a46eb9SPierre Jolivet for (i = 0; i < nv; i++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, vids[i])); 10359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 10368135c375SStefano Zampini vp--; 10378135c375SStefano Zampini break; 10388135c375SStefano Zampini case 4: /* face */ 10399566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeChildren(dm, parent, &numChildren, &children)); 10408135c375SStefano Zampini for (n = 0; n < numChildren; n++) { 10419566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dlabel, children[n], &depth)); 10428135c375SStefano Zampini if (!depth) { 10438135c375SStefano Zampini const PetscInt *hvsupp, *hesupp, *cone; 10448135c375SStefano Zampini PetscInt hvsuppSize, hesuppSize, coneSize; 1045451a39c7SStefano Zampini PetscInt hv = children[n], he = -1, f; 10468135c375SStefano Zampini 10479566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(skip, maxsupp)); 10489566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dm, hv, &hvsuppSize)); 10499566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, hv, &hvsupp)); 10508135c375SStefano Zampini for (i = 0; i < hvsuppSize; i++) { 10518135c375SStefano Zampini PetscInt ep; 10529566063dSJacob Faibussowitsch PetscCall(DMPlexGetTreeParent(dm, hvsupp[i], &ep, NULL)); 10538135c375SStefano Zampini if (ep != hvsupp[i]) { 10548135c375SStefano Zampini he = hvsupp[i]; 10558135c375SStefano Zampini } else { 10568135c375SStefano Zampini skip[i] = PETSC_TRUE; 10578135c375SStefano Zampini } 10588135c375SStefano Zampini } 105963a3b9bcSJacob Faibussowitsch PetscCheck(he != -1, PETSC_COMM_SELF, PETSC_ERR_SUP, "Vertex %" PetscInt_FMT " support size %" PetscInt_FMT ": hanging edge not found", hv, hvsuppSize); 10609566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, he, &cone)); 106196ca5757SLisandro Dalcin vids[0] = (cone[0] == hv) ? cone[1] : cone[0]; 10629566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupportSize(dm, he, &hesuppSize)); 10639566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, he, &hesupp)); 10648135c375SStefano Zampini for (f = 0; f < hesuppSize; f++) { 10658135c375SStefano Zampini PetscInt j; 10668135c375SStefano Zampini 10679566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, hesupp[f], &cone)); 10689566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, hesupp[f], &coneSize)); 10698135c375SStefano Zampini for (j = 0; j < coneSize; j++) { 10708135c375SStefano Zampini PetscInt k; 10718135c375SStefano Zampini for (k = 0; k < hvsuppSize; k++) { 10728135c375SStefano Zampini if (hvsupp[k] == cone[j]) { 10738135c375SStefano Zampini skip[k] = PETSC_TRUE; 10748135c375SStefano Zampini break; 10758135c375SStefano Zampini } 10768135c375SStefano Zampini } 10778135c375SStefano Zampini } 10788135c375SStefano Zampini } 10798135c375SStefano Zampini for (i = 0; i < hvsuppSize; i++) { 10808135c375SStefano Zampini if (!skip[i]) { 10819566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, hvsupp[i], &cone)); 108296ca5757SLisandro Dalcin vids[1] = (cone[0] == hv) ? cone[1] : cone[0]; 10838135c375SStefano Zampini } 10848135c375SStefano Zampini } 108563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, hv - vStart)); 1086*48a46eb9SPierre Jolivet for (i = 0; i < 2; i++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, vids[i] - vStart)); 10879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 10888135c375SStefano Zampini vp--; 10898135c375SStefano Zampini } 10908135c375SStefano Zampini } 10918135c375SStefano Zampini break; 10929371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Don't know how to deal with support size %" PetscInt_FMT, ssize); 10938135c375SStefano Zampini } 10948135c375SStefano Zampini } 10958135c375SStefano Zampini } 10969566063dSJacob Faibussowitsch PetscCall(PetscFree(skip)); 10978135c375SStefano Zampini } 109863a3b9bcSJacob Faibussowitsch PetscCheck(!vp, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected %" PetscInt_FMT " hanging vertices", vp); 10998135c375SStefano Zampini } 11009566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&vown)); 11018135c375SStefano Zampini 11028135c375SStefano Zampini /* vertices */ 110377eacf09SStefano Zampini if (hovec) { /* higher-order meshes */ 110477eacf09SStefano Zampini const char *fec; 11050286d493SLisandro Dalcin PetscInt i, n, s; 11069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nvertices\n")); 110763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", vEnd - vStart)); 11089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "nodes\n")); 11099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)hovec, &fec)); 11109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "FiniteElementSpace\n")); 11119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", fec)); 111263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "VDim: %" PetscInt_FMT "\n", sdim)); 11139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Ordering: 1\n\n")); /*Ordering::byVDIM*/ 11140c2bc6bfSStefano Zampini if (hoSection) { 11150c2bc6bfSStefano Zampini DM cdm; 11160c2bc6bfSStefano Zampini 11170c2bc6bfSStefano Zampini PetscCall(VecGetDM(hovec, &cdm)); 11180c2bc6bfSStefano Zampini for (p = cStart; p < cEnd; p++) { 11190c2bc6bfSStefano Zampini PetscScalar *vals = NULL; 11200c2bc6bfSStefano Zampini PetscInt csize; 11210c2bc6bfSStefano Zampini 11220c2bc6bfSStefano Zampini if (PetscUnlikely(pown && !PetscBTLookup(pown, p - cStart))) continue; 11230c2bc6bfSStefano Zampini PetscCall(DMPlexVecGetClosure(cdm, hoSection, hovec, p, &csize, &vals)); 112463a3b9bcSJacob Faibussowitsch PetscCheck(csize % sdim == 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Size of closure %" PetscInt_FMT " incompatible with space dimension %" PetscInt_FMT, csize, sdim); 11250c2bc6bfSStefano Zampini for (i = 0; i < csize / sdim; i++) { 1126*48a46eb9SPierre Jolivet for (s = 0; s < sdim; s++) PetscCall(PetscViewerASCIIPrintf(viewer, fmt, (double)PetscRealPart(vals[i * sdim + s]))); 11270c2bc6bfSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 11280c2bc6bfSStefano Zampini } 11290c2bc6bfSStefano Zampini PetscCall(DMPlexVecRestoreClosure(cdm, hoSection, hovec, p, &csize, &vals)); 11300c2bc6bfSStefano Zampini } 11310c2bc6bfSStefano Zampini } else { 11329566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(hovec, &array)); 11339566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(hovec, &n)); 113463a3b9bcSJacob Faibussowitsch PetscCheck(n % sdim == 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Size of local coordinate vector %" PetscInt_FMT " incompatible with space dimension %" PetscInt_FMT, n, sdim); 113577eacf09SStefano Zampini for (i = 0; i < n / sdim; i++) { 1136*48a46eb9SPierre Jolivet for (s = 0; s < sdim; s++) PetscCall(PetscViewerASCIIPrintf(viewer, fmt, (double)PetscRealPart(array[i * sdim + s]))); 11379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 113877eacf09SStefano Zampini } 11399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(hovec, &array)); 11400c2bc6bfSStefano Zampini } 114177eacf09SStefano Zampini } else { 11429566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(coordinates, &nvert)); 11439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\nvertices\n")); 114463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", nvert / sdim)); 114563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT "\n", sdim)); 11469566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coordinates, &array)); 1147cc0d3ed7SStefano Zampini for (p = 0; p < nvert / sdim; p++) { 1148cc0d3ed7SStefano Zampini PetscInt s; 1149cc0d3ed7SStefano Zampini for (s = 0; s < sdim; s++) { 11503e96840aSStefano Zampini PetscReal v = PetscRealPart(array[p * sdim + s]); 11513e96840aSStefano Zampini 11529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, fmt, PetscIsInfOrNanReal(v) ? 0.0 : (double)v)); 11538135c375SStefano Zampini } 11549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 11558135c375SStefano Zampini } 11569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coordinates, &array)); 115777eacf09SStefano Zampini } 11580c2bc6bfSStefano Zampini PetscCall(PetscBTDestroy(&pown)); 11599566063dSJacob Faibussowitsch PetscCall(VecDestroy(&hovec)); 11608135c375SStefano Zampini PetscFunctionReturn(0); 11618135c375SStefano Zampini } 11628135c375SStefano Zampini 11639371c9d4SSatish Balay PetscErrorCode DMPlexView_GLVis(DM dm, PetscViewer viewer) { 11648135c375SStefano Zampini PetscFunctionBegin; 11659566063dSJacob Faibussowitsch PetscCall(DMView_GLVis(dm, viewer, DMPlexView_GLVis_ASCII)); 11668135c375SStefano Zampini PetscFunctionReturn(0); 11678135c375SStefano Zampini } 1168