15808f684SSatish Balay{ 25808f684SSatish Balay "cells": [ 35808f684SSatish Balay { 45808f684SSatish Balay "cell_type": "markdown", 55808f684SSatish Balay "metadata": {}, 65808f684SSatish Balay "source": [ 75808f684SSatish Balay "Decoding the DMPlex\n", 85808f684SSatish Balay "===================\n", 95808f684SSatish Balay "\n", 105808f684SSatish Balay "The purpose of this notebook is to provide a tutorial for the DMPlex features in PETSc. DMPlex and its sub-objects are an attempt to properly abstract out the concept of grids and the assignment of degree of freedom information to entities in that grid. The hope is that this will allow for easy implementation of different discretization ideas and subsequently lead to their fair comparison. To be able to use DMPlex you need to speak its language and understand how to get the information your methods need. In this tutorial I will explain and demonstrate the functionality of the DMPlex API." 115808f684SSatish Balay ] 125808f684SSatish Balay }, 135808f684SSatish Balay { 145808f684SSatish Balay "cell_type": "code", 157d5fd1e4SRichard Tran Mills "execution_count": 4, 167d5fd1e4SRichard Tran Mills "metadata": {}, 177d5fd1e4SRichard Tran Mills "outputs": [], 187d5fd1e4SRichard Tran Mills "source": [ 197d5fd1e4SRichard Tran Mills "from __future__ import print_function\n", 205808f684SSatish Balay "import sys,petsc4py\n", 215808f684SSatish Balay "petsc4py.init(sys.argv)\n", 225808f684SSatish Balay "from petsc4py import PETSc\n", 235808f684SSatish Balay "import numpy as np" 247d5fd1e4SRichard Tran Mills ] 255808f684SSatish Balay }, 265808f684SSatish Balay { 275808f684SSatish Balay "cell_type": "markdown", 285808f684SSatish Balay "metadata": {}, 295808f684SSatish Balay "source": [ 305808f684SSatish Balay "One way to create a DMPlex is to specify coordinates of vertices and cell connectivities. Here we encode a simple 2 by 2 element mesh of quads." 315808f684SSatish Balay ] 325808f684SSatish Balay }, 335808f684SSatish Balay { 345808f684SSatish Balay "cell_type": "code", 357d5fd1e4SRichard Tran Mills "execution_count": 5, 367d5fd1e4SRichard Tran Mills "metadata": {}, 377d5fd1e4SRichard Tran Mills "outputs": [], 387d5fd1e4SRichard Tran Mills "source": [ 395808f684SSatish Balay "dim = 2\n", 405808f684SSatish Balay "coords = np.asarray([[0.0, 0.0],\n", 415808f684SSatish Balay " [0.5, 0.0],\n", 425808f684SSatish Balay " [1.0, 0.0],\n", 435808f684SSatish Balay " [0.0, 0.5],\n", 445808f684SSatish Balay " [0.5, 0.5],\n", 455808f684SSatish Balay " [1.0, 0.5],\n", 465808f684SSatish Balay " [0.0, 1.0],\n", 475808f684SSatish Balay " [0.5, 1.0],\n", 485808f684SSatish Balay " [1.0, 1.0]])\n", 495808f684SSatish Balay "cells = np.asarray([[0,1,4,3],\n", 505808f684SSatish Balay " [1,2,5,4],\n", 515808f684SSatish Balay " [3,4,7,6],\n", 525808f684SSatish Balay " [4,5,8,7]],dtype='int32')" 537d5fd1e4SRichard Tran Mills ] 545808f684SSatish Balay }, 555808f684SSatish Balay { 565808f684SSatish Balay "cell_type": "markdown", 575808f684SSatish Balay "metadata": {}, 585808f684SSatish Balay "source": [ 595808f684SSatish Balay "Now we initialize the DMPlex using this mesh information. " 605808f684SSatish Balay ] 615808f684SSatish Balay }, 625808f684SSatish Balay { 635808f684SSatish Balay "cell_type": "code", 647d5fd1e4SRichard Tran Mills "execution_count": 6, 655808f684SSatish Balay "metadata": {}, 665808f684SSatish Balay "outputs": [], 677d5fd1e4SRichard Tran Mills "source": [ 687d5fd1e4SRichard Tran Mills "plex = PETSc.DMPlex().createFromCellList(dim,cells,coords)" 697d5fd1e4SRichard Tran Mills ] 705808f684SSatish Balay }, 715808f684SSatish Balay { 725808f684SSatish Balay "cell_type": "markdown", 735808f684SSatish Balay "metadata": {}, 745808f684SSatish Balay "source": [ 75*aaa8cc7dSPierre Jolivet "PETSc converts the mesh into their abstraction of a topology which they store as a Hasse Diagram. Essentially this is a list of integers which encodes all the entities of each dimension. We can use the view method to see what the DMPlex has encoded (broken, prints to the terminal but not here, capture magic doesn't work)." 765808f684SSatish Balay ] 775808f684SSatish Balay }, 785808f684SSatish Balay { 795808f684SSatish Balay "cell_type": "code", 807d5fd1e4SRichard Tran Mills "execution_count": 7, 815808f684SSatish Balay "metadata": {}, 825808f684SSatish Balay "outputs": [], 837d5fd1e4SRichard Tran Mills "source": [ 847d5fd1e4SRichard Tran Mills "plex.view()" 857d5fd1e4SRichard Tran Mills ] 865808f684SSatish Balay }, 875808f684SSatish Balay { 885808f684SSatish Balay "cell_type": "markdown", 895808f684SSatish Balay "metadata": {}, 905808f684SSatish Balay "source": [ 915808f684SSatish Balay "The view reveals that we have a mesh in 2 dimensions and that we have 9 0-cells (vertices), 12 1-cells (edges), and 4 2-cells (quads). All mesh entities are stored as integers in a single array called a chart. Each entity in the chart is called a point. (At this point it would be good to make some kind of plot with all points numbered, I suggest sketching one.)\n", 925808f684SSatish Balay "\n", 935808f684SSatish Balay "Cones and Supports\n", 945808f684SSatish Balay "------------------\n", 955808f684SSatish Balay "\n", 965808f684SSatish Balay "The *cone* of a point consists of the points of a dimension lower which make up that entity. So we can loop through the chart and print out each points' cone." 975808f684SSatish Balay ] 985808f684SSatish Balay }, 995808f684SSatish Balay { 1005808f684SSatish Balay "cell_type": "code", 1017d5fd1e4SRichard Tran Mills "execution_count": 8, 1025808f684SSatish Balay "metadata": {}, 1035808f684SSatish Balay "outputs": [ 1045808f684SSatish Balay { 1057d5fd1e4SRichard Tran Mills "name": "stdout", 1065808f684SSatish Balay "output_type": "stream", 1075808f684SSatish Balay "text": [ 1085808f684SSatish Balay "point = 0 \tcone = [13 14 15 16]\n", 1095808f684SSatish Balay "point = 1 \tcone = [17 18 19 14]\n", 1105808f684SSatish Balay "point = 2 \tcone = [15 20 21 22]\n", 1115808f684SSatish Balay "point = 3 \tcone = [19 23 24 20]\n", 1125808f684SSatish Balay "point = 4 \tcone = []\n", 1135808f684SSatish Balay "point = 5 \tcone = []\n", 1145808f684SSatish Balay "point = 6 \tcone = []\n", 1155808f684SSatish Balay "point = 7 \tcone = []\n", 1165808f684SSatish Balay "point = 8 \tcone = []\n", 1175808f684SSatish Balay "point = 9 \tcone = []\n", 1185808f684SSatish Balay "point = 10 \tcone = []\n", 1195808f684SSatish Balay "point = 11 \tcone = []\n", 1205808f684SSatish Balay "point = 12 \tcone = []\n", 1215808f684SSatish Balay "point = 13 \tcone = [4 5]\n", 1225808f684SSatish Balay "point = 14 \tcone = [5 8]\n", 1235808f684SSatish Balay "point = 15 \tcone = [8 7]\n", 1245808f684SSatish Balay "point = 16 \tcone = [7 4]\n", 1255808f684SSatish Balay "point = 17 \tcone = [5 6]\n", 1265808f684SSatish Balay "point = 18 \tcone = [6 9]\n", 1275808f684SSatish Balay "point = 19 \tcone = [9 8]\n", 1285808f684SSatish Balay "point = 20 \tcone = [ 8 11]\n", 1295808f684SSatish Balay "point = 21 \tcone = [11 10]\n", 1305808f684SSatish Balay "point = 22 \tcone = [10 7]\n", 1315808f684SSatish Balay "point = 23 \tcone = [ 9 12]\n", 1325808f684SSatish Balay "point = 24 \tcone = [12 11]\n" 1335808f684SSatish Balay ] 1345808f684SSatish Balay } 1355808f684SSatish Balay ], 1367d5fd1e4SRichard Tran Mills "source": [ 1377d5fd1e4SRichard Tran Mills "pStart,pEnd = plex.getChart()\n", 1387d5fd1e4SRichard Tran Mills "for i in range(pStart,pEnd):\n", 1397d5fd1e4SRichard Tran Mills " print(\"point =\", i, \"\\tcone =\", plex.getCone(i))" 1407d5fd1e4SRichard Tran Mills ] 1415808f684SSatish Balay }, 1425808f684SSatish Balay { 1435808f684SSatish Balay "cell_type": "markdown", 1445808f684SSatish Balay "metadata": {}, 1455808f684SSatish Balay "source": [ 1465808f684SSatish Balay "Note that the numbering is completely different from our original mesh encoding. Here we summarize what we observe from the cones of the chart entities.\n", 1475808f684SSatish Balay "\n", 1485808f684SSatish Balay "* Points 0 through 3 correspond to quad cells. So their cones are made up of lists of 4 integers which refer to the lower dimensional entities which make up that cell--the edges. \n", 1495808f684SSatish Balay "* Points 4 through 12 correspond to vertices. These are the lowest dimensional object we have and thus they are empty.\n", 1505808f684SSatish Balay "* Points 13 through 24 correspond to edges. Each edge is made up of two vertices.\n", 1515808f684SSatish Balay "\n", 1525808f684SSatish Balay "Similarly, each point has a support. The *support* of a point is the list which consists of points of a higher dimension which contain the point in its cone. So we can now repeat the above exercise but for the support." 1535808f684SSatish Balay ] 1545808f684SSatish Balay }, 1555808f684SSatish Balay { 1565808f684SSatish Balay "cell_type": "code", 1577d5fd1e4SRichard Tran Mills "execution_count": 10, 1585808f684SSatish Balay "metadata": {}, 1595808f684SSatish Balay "outputs": [ 1605808f684SSatish Balay { 1617d5fd1e4SRichard Tran Mills "name": "stdout", 1625808f684SSatish Balay "output_type": "stream", 1635808f684SSatish Balay "text": [ 1645808f684SSatish Balay "point = 0 \tsupport = []\n", 1655808f684SSatish Balay "point = 1 \tsupport = []\n", 1665808f684SSatish Balay "point = 2 \tsupport = []\n", 1675808f684SSatish Balay "point = 3 \tsupport = []\n", 1685808f684SSatish Balay "point = 4 \tsupport = [13 16]\n", 1695808f684SSatish Balay "point = 5 \tsupport = [13 14 17]\n", 1705808f684SSatish Balay "point = 6 \tsupport = [17 18]\n", 1715808f684SSatish Balay "point = 7 \tsupport = [15 16 22]\n", 1725808f684SSatish Balay "point = 8 \tsupport = [14 15 19 20]\n", 1735808f684SSatish Balay "point = 9 \tsupport = [18 19 23]\n", 1745808f684SSatish Balay "point = 10 \tsupport = [21 22]\n", 1755808f684SSatish Balay "point = 11 \tsupport = [20 21 24]\n", 1765808f684SSatish Balay "point = 12 \tsupport = [23 24]\n", 1775808f684SSatish Balay "point = 13 \tsupport = [0]\n", 1785808f684SSatish Balay "point = 14 \tsupport = [0 1]\n", 1795808f684SSatish Balay "point = 15 \tsupport = [0 2]\n", 1805808f684SSatish Balay "point = 16 \tsupport = [0]\n", 1815808f684SSatish Balay "point = 17 \tsupport = [1]\n", 1825808f684SSatish Balay "point = 18 \tsupport = [1]\n", 1835808f684SSatish Balay "point = 19 \tsupport = [1 3]\n", 1845808f684SSatish Balay "point = 20 \tsupport = [2 3]\n", 1855808f684SSatish Balay "point = 21 \tsupport = [2]\n", 1865808f684SSatish Balay "point = 22 \tsupport = [2]\n", 1875808f684SSatish Balay "point = 23 \tsupport = [3]\n", 1885808f684SSatish Balay "point = 24 \tsupport = [3]\n" 1895808f684SSatish Balay ] 1905808f684SSatish Balay } 1915808f684SSatish Balay ], 1927d5fd1e4SRichard Tran Mills "source": [ 1937d5fd1e4SRichard Tran Mills "for i in range(pStart,pEnd):\n", 1947d5fd1e4SRichard Tran Mills " print(\"point =\", i, \"\\tsupport =\", plex.getSupport(i))" 1957d5fd1e4SRichard Tran Mills ] 1965808f684SSatish Balay }, 1975808f684SSatish Balay { 1985808f684SSatish Balay "cell_type": "markdown", 1995808f684SSatish Balay "metadata": {}, 2005808f684SSatish Balay "source": [ 2015808f684SSatish Balay "* Points 0 through 3 (quads) have no support, there is nothing of higher dimension in this mesh\n", 2025808f684SSatish Balay "* Points 4 through 12 (vertices) have at least 2 edges in their support and the middle (8) has 4 edges\n", 2035808f684SSatish Balay "* Points 13 through 24 (edges) have at least 1 cell in their support as many as 2\n", 2045808f684SSatish Balay "\n", 2055808f684SSatish Balay "So the DMPlex is a dimension-independent, low memory, abstract representation of a topology which we use to represent grid objects. The DMPlex knows nothing about elements, basis functions, fluxes, degrees of freedom, etc. It is just the topology itself and is completely general. DMPlex can be used to construct any kind of topological relation. Here we created one from a cell list and then accessed its cone/support information. A DMPlex can also be built by hand using the appropriate *set* routines or with other kinds of constructors available in the API.\n", 2065808f684SSatish Balay "\n", 2075808f684SSatish Balay "Labeling\n", 2085808f684SSatish Balay "--------\n", 2095808f684SSatish Balay "\n", 2105808f684SSatish Balay "DMPlex provides support for the labeling of points. This can be helpful if you would like to flag certain entities for some reason. By default, the DMPlex comes with a label called 'depth'. This labels each entity based on how deep it is in the chart. You could also think of it as the dimensionality of the objects. Here we can check that the label does exist." 2115808f684SSatish Balay ] 2125808f684SSatish Balay }, 2135808f684SSatish Balay { 2145808f684SSatish Balay "cell_type": "code", 2157d5fd1e4SRichard Tran Mills "execution_count": 12, 2165808f684SSatish Balay "metadata": {}, 2175808f684SSatish Balay "outputs": [ 2185808f684SSatish Balay { 2197d5fd1e4SRichard Tran Mills "name": "stdout", 2205808f684SSatish Balay "output_type": "stream", 2215808f684SSatish Balay "text": [ 2227d5fd1e4SRichard Tran Mills "label name = celltype \tlabel size = 3\n", 2235808f684SSatish Balay "label name = depth \tlabel size = 3\n" 2245808f684SSatish Balay ] 2255808f684SSatish Balay } 2265808f684SSatish Balay ], 2277d5fd1e4SRichard Tran Mills "source": [ 2287d5fd1e4SRichard Tran Mills "for i in range(plex.getNumLabels()):\n", 2297d5fd1e4SRichard Tran Mills " name = plex.getLabelName(i)\n", 2307d5fd1e4SRichard Tran Mills " print(\"label name = %s\" % name, \"\\tlabel size = %d\" % plex.getLabelSize(name))" 2317d5fd1e4SRichard Tran Mills ] 2325808f684SSatish Balay }, 2335808f684SSatish Balay { 2345808f684SSatish Balay "cell_type": "markdown", 2355808f684SSatish Balay "metadata": {}, 2365808f684SSatish Balay "source": [ 2375808f684SSatish Balay "So the label 'depth' does exist and we see that there are 3 different entries. Now we will loop over each item in the DMPlex and print the value of the label." 2385808f684SSatish Balay ] 2395808f684SSatish Balay }, 2405808f684SSatish Balay { 2415808f684SSatish Balay "cell_type": "code", 2427d5fd1e4SRichard Tran Mills "execution_count": 15, 2435808f684SSatish Balay "metadata": {}, 2445808f684SSatish Balay "outputs": [ 2455808f684SSatish Balay { 2467d5fd1e4SRichard Tran Mills "name": "stdout", 2475808f684SSatish Balay "output_type": "stream", 2485808f684SSatish Balay "text": [ 2495808f684SSatish Balay "point = 0 \tlabel(depth) = 2\n", 2505808f684SSatish Balay "point = 1 \tlabel(depth) = 2\n", 2515808f684SSatish Balay "point = 2 \tlabel(depth) = 2\n", 2525808f684SSatish Balay "point = 3 \tlabel(depth) = 2\n", 2535808f684SSatish Balay "point = 4 \tlabel(depth) = 0\n", 2545808f684SSatish Balay "point = 5 \tlabel(depth) = 0\n", 2555808f684SSatish Balay "point = 6 \tlabel(depth) = 0\n", 2565808f684SSatish Balay "point = 7 \tlabel(depth) = 0\n", 2575808f684SSatish Balay "point = 8 \tlabel(depth) = 0\n", 2585808f684SSatish Balay "point = 9 \tlabel(depth) = 0\n", 2595808f684SSatish Balay "point = 10 \tlabel(depth) = 0\n", 2605808f684SSatish Balay "point = 11 \tlabel(depth) = 0\n", 2615808f684SSatish Balay "point = 12 \tlabel(depth) = 0\n", 2625808f684SSatish Balay "point = 13 \tlabel(depth) = 1\n", 2635808f684SSatish Balay "point = 14 \tlabel(depth) = 1\n", 2645808f684SSatish Balay "point = 15 \tlabel(depth) = 1\n", 2655808f684SSatish Balay "point = 16 \tlabel(depth) = 1\n", 2665808f684SSatish Balay "point = 17 \tlabel(depth) = 1\n", 2675808f684SSatish Balay "point = 18 \tlabel(depth) = 1\n", 2685808f684SSatish Balay "point = 19 \tlabel(depth) = 1\n", 2695808f684SSatish Balay "point = 20 \tlabel(depth) = 1\n", 2705808f684SSatish Balay "point = 21 \tlabel(depth) = 1\n", 2715808f684SSatish Balay "point = 22 \tlabel(depth) = 1\n", 2725808f684SSatish Balay "point = 23 \tlabel(depth) = 1\n", 2735808f684SSatish Balay "point = 24 \tlabel(depth) = 1\n" 2745808f684SSatish Balay ] 2755808f684SSatish Balay } 2765808f684SSatish Balay ], 2777d5fd1e4SRichard Tran Mills "source": [ 2787d5fd1e4SRichard Tran Mills "for i in range(pStart,pEnd):\n", 2797d5fd1e4SRichard Tran Mills " print(\"point =\",i, \"\\tlabel(depth) = %d\" % plex.getLabelValue(\"depth\",i))" 2807d5fd1e4SRichard Tran Mills ] 2815808f684SSatish Balay }, 2825808f684SSatish Balay { 2835808f684SSatish Balay "cell_type": "markdown", 2845808f684SSatish Balay "metadata": {}, 2855808f684SSatish Balay "source": [ 2865808f684SSatish Balay "The depths listed match our intuition of which entities were which when we looked at the cones and support. The DMPlex has support for identifying the range of indices in the chart which correspond to each value of the depth, the so-called *depth stratum*. (I do not understand what height stratum is for yet)" 2875808f684SSatish Balay ] 2885808f684SSatish Balay }, 2895808f684SSatish Balay { 2905808f684SSatish Balay "cell_type": "code", 2917d5fd1e4SRichard Tran Mills "execution_count": 22, 2925808f684SSatish Balay "metadata": {}, 2935808f684SSatish Balay "outputs": [ 2945808f684SSatish Balay { 2957d5fd1e4SRichard Tran Mills "name": "stdout", 2965808f684SSatish Balay "output_type": "stream", 2975808f684SSatish Balay "text": [ 2985808f684SSatish Balay "depth = 0 \tdepth stratum = (4, 13) \theight stratum = (0, 4)\n", 2995808f684SSatish Balay "depth = 1 \tdepth stratum = (13, 25) \theight stratum = (13, 25)\n", 3005808f684SSatish Balay "depth = 2 \tdepth stratum = (0, 4) \theight stratum = (4, 13)\n" 3015808f684SSatish Balay ] 3025808f684SSatish Balay } 3035808f684SSatish Balay ], 3047d5fd1e4SRichard Tran Mills "source": [ 3057d5fd1e4SRichard Tran Mills "for i in range(plex.getDepth()+1):\n", 3067d5fd1e4SRichard Tran Mills " print(\"depth = %d\" % i,\"\\tdepth stratum = \",plex.getDepthStratum(i),\"\\theight stratum = \",plex.getHeightStratum(i))" 3077d5fd1e4SRichard Tran Mills ] 3085808f684SSatish Balay }, 3095808f684SSatish Balay { 3105808f684SSatish Balay "cell_type": "markdown", 3115808f684SSatish Balay "metadata": {}, 3125808f684SSatish Balay "source": [ 3135808f684SSatish Balay "We can also use labels to mark, say, boundary edges. These are the edges with only 1 entry in the support." 3145808f684SSatish Balay ] 3155808f684SSatish Balay }, 3165808f684SSatish Balay { 3175808f684SSatish Balay "cell_type": "code", 3187d5fd1e4SRichard Tran Mills "execution_count": 23, 3195808f684SSatish Balay "metadata": {}, 3205808f684SSatish Balay "outputs": [ 3215808f684SSatish Balay { 3227d5fd1e4SRichard Tran Mills "name": "stdout", 3235808f684SSatish Balay "output_type": "stream", 3245808f684SSatish Balay "text": [ 3255808f684SSatish Balay "point = 0 \tlabel(boundary) = -1\n", 3265808f684SSatish Balay "point = 1 \tlabel(boundary) = -1\n", 3275808f684SSatish Balay "point = 2 \tlabel(boundary) = -1\n", 3285808f684SSatish Balay "point = 3 \tlabel(boundary) = -1\n", 3295808f684SSatish Balay "point = 4 \tlabel(boundary) = -1\n", 3305808f684SSatish Balay "point = 5 \tlabel(boundary) = -1\n", 3315808f684SSatish Balay "point = 6 \tlabel(boundary) = -1\n", 3325808f684SSatish Balay "point = 7 \tlabel(boundary) = -1\n", 3335808f684SSatish Balay "point = 8 \tlabel(boundary) = -1\n", 3345808f684SSatish Balay "point = 9 \tlabel(boundary) = -1\n", 3355808f684SSatish Balay "point = 10 \tlabel(boundary) = -1\n", 3365808f684SSatish Balay "point = 11 \tlabel(boundary) = -1\n", 3375808f684SSatish Balay "point = 12 \tlabel(boundary) = -1\n", 3385808f684SSatish Balay "point = 13 \tlabel(boundary) = 1\n", 3395808f684SSatish Balay "point = 14 \tlabel(boundary) = -1\n", 3405808f684SSatish Balay "point = 15 \tlabel(boundary) = -1\n", 3415808f684SSatish Balay "point = 16 \tlabel(boundary) = 1\n", 3425808f684SSatish Balay "point = 17 \tlabel(boundary) = 1\n", 3435808f684SSatish Balay "point = 18 \tlabel(boundary) = 1\n", 3445808f684SSatish Balay "point = 19 \tlabel(boundary) = -1\n", 3455808f684SSatish Balay "point = 20 \tlabel(boundary) = -1\n", 3465808f684SSatish Balay "point = 21 \tlabel(boundary) = 1\n", 3475808f684SSatish Balay "point = 22 \tlabel(boundary) = 1\n", 3485808f684SSatish Balay "point = 23 \tlabel(boundary) = 1\n", 3495808f684SSatish Balay "point = 24 \tlabel(boundary) = 1\n" 3505808f684SSatish Balay ] 3515808f684SSatish Balay } 3525808f684SSatish Balay ], 3537d5fd1e4SRichard Tran Mills "source": [ 3547d5fd1e4SRichard Tran Mills "plex.createLabel(\"boundary\")\n", 3557d5fd1e4SRichard Tran Mills "for i in range(pStart,pEnd):\n", 3567d5fd1e4SRichard Tran Mills " if plex.getLabelValue(\"depth\",i) == 1: # this is an edge\n", 3577d5fd1e4SRichard Tran Mills " if plex.getSupportSize(i) == 1: # only one cell has it as an edge\n", 3587d5fd1e4SRichard Tran Mills " plex.setLabelValue(\"boundary\",i,1)\n", 3597d5fd1e4SRichard Tran Mills " print(\"point =\", i, \"\\tlabel(boundary) = %d\" % plex.getLabelValue(\"boundary\",i))" 3607d5fd1e4SRichard Tran Mills ] 3615808f684SSatish Balay }, 3625808f684SSatish Balay { 3635808f684SSatish Balay "cell_type": "markdown", 3645808f684SSatish Balay "metadata": {}, 3655808f684SSatish Balay "source": [ 3665808f684SSatish Balay "The default values are set to -1 and the boundary edges were marked with a 1. Labels aren't so useful on their own--the useful part about labeling things is that you can also get index sets of all entities with the same value of label. This means that if we wanted an index set which maps vertex numbers to the chartID we can get the PETSc IS for the 'depth' label for a value of 0 (again view doesn't print here)." 3675808f684SSatish Balay ] 3685808f684SSatish Balay }, 3695808f684SSatish Balay { 3705808f684SSatish Balay "cell_type": "code", 3717d5fd1e4SRichard Tran Mills "execution_count": 32, 3725808f684SSatish Balay "metadata": {}, 3735808f684SSatish Balay "outputs": [], 3747d5fd1e4SRichard Tran Mills "source": [ 3757d5fd1e4SRichard Tran Mills "vis = plex.getStratumIS(\"depth\",0)\n", 3767d5fd1e4SRichard Tran Mills "vis.view()" 3777d5fd1e4SRichard Tran Mills ] 3785808f684SSatish Balay }, 3795808f684SSatish Balay { 3805808f684SSatish Balay "cell_type": "markdown", 3815808f684SSatish Balay "metadata": {}, 3825808f684SSatish Balay "source": [ 3835808f684SSatish Balay "Note that there are also routines which would appear to do the same as the above. However, their index sets return a local to global mapping of vertices (smallest depth in chart) and cells (largest depth in chart) useful in parallel." 3845808f684SSatish Balay ] 3855808f684SSatish Balay }, 3865808f684SSatish Balay { 3875808f684SSatish Balay "cell_type": "code", 3887d5fd1e4SRichard Tran Mills "execution_count": 31, 3897d5fd1e4SRichard Tran Mills "metadata": {}, 3907d5fd1e4SRichard Tran Mills "outputs": [], 3917d5fd1e4SRichard Tran Mills "source": [ 3925808f684SSatish Balay "vis = plex.getVertexNumbering()\n", 3935808f684SSatish Balay "vis.view()\n", 3945808f684SSatish Balay "cis = plex.getCellNumbering()\n", 3955808f684SSatish Balay "cis.view()" 3967d5fd1e4SRichard Tran Mills ] 3975808f684SSatish Balay }, 3985808f684SSatish Balay { 3995808f684SSatish Balay "cell_type": "markdown", 4005808f684SSatish Balay "metadata": {}, 4015808f684SSatish Balay "source": [ 4025808f684SSatish Balay "Meets and Joins\n", 4035808f684SSatish Balay "---------------\n", 4045808f684SSatish Balay "\n", 4055808f684SSatish Balay "Many times in performing grid operations, you need to know how lower and/or higher dimensional items are connected to each other. In the PETSc parlance, these are called *meets* and *joins*. A *meet* of a set of points is the intersection of the points' cones and a *join* is the intersection of the points' support. Here we demonstrate the concept with a few examples." 4065808f684SSatish Balay ] 4075808f684SSatish Balay }, 4085808f684SSatish Balay { 4095808f684SSatish Balay "cell_type": "code", 4107d5fd1e4SRichard Tran Mills "execution_count": 25, 4115808f684SSatish Balay "metadata": {}, 4125808f684SSatish Balay "outputs": [ 4135808f684SSatish Balay { 4147d5fd1e4SRichard Tran Mills "name": "stdout", 4155808f684SSatish Balay "output_type": "stream", 4165808f684SSatish Balay "text": [ 4175808f684SSatish Balay "meet = [14] \tjoin = []\n" 4185808f684SSatish Balay ] 4195808f684SSatish Balay } 4205808f684SSatish Balay ], 4217d5fd1e4SRichard Tran Mills "source": [ 4227d5fd1e4SRichard Tran Mills "# Two cells, meet is the common edge, no join\n", 4237d5fd1e4SRichard Tran Mills "pnts = [0,1]\n", 4247d5fd1e4SRichard Tran Mills "print(\"meet =\",plex.getMeet(pnts),\"\\tjoin =\",plex.getJoin(pnts))" 4257d5fd1e4SRichard Tran Mills ] 4265808f684SSatish Balay }, 4275808f684SSatish Balay { 4285808f684SSatish Balay "cell_type": "code", 4297d5fd1e4SRichard Tran Mills "execution_count": 26, 4305808f684SSatish Balay "metadata": {}, 4315808f684SSatish Balay "outputs": [ 4325808f684SSatish Balay { 4337d5fd1e4SRichard Tran Mills "name": "stdout", 4345808f684SSatish Balay "output_type": "stream", 4355808f684SSatish Balay "text": [ 4365808f684SSatish Balay "meet = [8] \tjoin = [1]\n" 4375808f684SSatish Balay ] 4385808f684SSatish Balay } 4395808f684SSatish Balay ], 4407d5fd1e4SRichard Tran Mills "source": [ 4417d5fd1e4SRichard Tran Mills "# Two edges, meet is the common vertex, join is the cell to which they are both connected\n", 4427d5fd1e4SRichard Tran Mills "pnts = [14,19]\n", 4437d5fd1e4SRichard Tran Mills "print(\"meet =\",plex.getMeet(pnts),\"\\tjoin =\",plex.getJoin(pnts))" 4447d5fd1e4SRichard Tran Mills ] 4455808f684SSatish Balay }, 4465808f684SSatish Balay { 4475808f684SSatish Balay "cell_type": "code", 4487d5fd1e4SRichard Tran Mills "execution_count": 27, 4495808f684SSatish Balay "metadata": {}, 4505808f684SSatish Balay "outputs": [ 4515808f684SSatish Balay { 4527d5fd1e4SRichard Tran Mills "name": "stdout", 4535808f684SSatish Balay "output_type": "stream", 4545808f684SSatish Balay "text": [ 4555808f684SSatish Balay "meet = [] \tjoin = [20]\n" 4565808f684SSatish Balay ] 4575808f684SSatish Balay } 4585808f684SSatish Balay ], 4597d5fd1e4SRichard Tran Mills "source": [ 4607d5fd1e4SRichard Tran Mills "# Two vertices, no meet, join is the common edge to which they are both connected\n", 4617d5fd1e4SRichard Tran Mills "pnts = [8,11]\n", 4627d5fd1e4SRichard Tran Mills "print(\"meet =\",plex.getMeet(pnts),\"\\tjoin =\",plex.getJoin(pnts))" 4637d5fd1e4SRichard Tran Mills ] 4645808f684SSatish Balay }, 4655808f684SSatish Balay { 4665808f684SSatish Balay "cell_type": "markdown", 4675808f684SSatish Balay "metadata": {}, 4685808f684SSatish Balay "source": [ 4695808f684SSatish Balay "Transitive Closure\n", 4705808f684SSatish Balay "------------------\n", 4715808f684SSatish Balay "\n", 4725808f684SSatish Balay "The transitive closure of a point in the DMPlex is a list of all reachable points from the given point, by default in the 'in-edge' direction. The transitive closure is then a set created by recursively taking the union on all points in the cone and its cones. In other words, it is all points of lower or equal dimension that this point can \"reach\". The routine also returns an array parallel to the closure array which defines how the points are oriented relative to the give point (e.g. for a cell, you might need to flip some edges to follow a right-handed convention). There is a flag in the routine, useCone, which if set to False will perform the same operation but in the 'out-edge' direction (that is, instead of recursively operating on cones, it will use the supports)." 4735808f684SSatish Balay ] 4745808f684SSatish Balay }, 4755808f684SSatish Balay { 4765808f684SSatish Balay "cell_type": "code", 4777d5fd1e4SRichard Tran Mills "execution_count": 30, 4785808f684SSatish Balay "metadata": {}, 4795808f684SSatish Balay "outputs": [ 4805808f684SSatish Balay { 4817d5fd1e4SRichard Tran Mills "name": "stdout", 4825808f684SSatish Balay "output_type": "stream", 4835808f684SSatish Balay "text": [ 4845808f684SSatish Balay "point = 0 \tclosure(cone) = [ 0 13 14 15 16 4 5 8 7] \tclosure(supp) = [0]\n", 4855808f684SSatish Balay "point = 1 \tclosure(cone) = [ 1 17 18 19 14 5 6 9 8] \tclosure(supp) = [1]\n", 4865808f684SSatish Balay "point = 2 \tclosure(cone) = [ 2 15 20 21 22 7 8 11 10] \tclosure(supp) = [2]\n", 4875808f684SSatish Balay "point = 3 \tclosure(cone) = [ 3 19 23 24 20 8 9 12 11] \tclosure(supp) = [3]\n", 4885808f684SSatish Balay "point = 4 \tclosure(cone) = [4] \tclosure(supp) = [ 4 13 16 0]\n", 4895808f684SSatish Balay "point = 5 \tclosure(cone) = [5] \tclosure(supp) = [ 5 13 14 17 0 1]\n", 4905808f684SSatish Balay "point = 6 \tclosure(cone) = [6] \tclosure(supp) = [ 6 17 18 1]\n", 4915808f684SSatish Balay "point = 7 \tclosure(cone) = [7] \tclosure(supp) = [ 7 15 16 22 0 2]\n", 4925808f684SSatish Balay "point = 8 \tclosure(cone) = [8] \tclosure(supp) = [ 8 14 15 19 20 0 1 2 3]\n", 4935808f684SSatish Balay "point = 9 \tclosure(cone) = [9] \tclosure(supp) = [ 9 18 19 23 1 3]\n", 4945808f684SSatish Balay "point = 10 \tclosure(cone) = [10] \tclosure(supp) = [10 21 22 2]\n", 4955808f684SSatish Balay "point = 11 \tclosure(cone) = [11] \tclosure(supp) = [11 20 21 24 2 3]\n", 4965808f684SSatish Balay "point = 12 \tclosure(cone) = [12] \tclosure(supp) = [12 23 24 3]\n", 4975808f684SSatish Balay "point = 13 \tclosure(cone) = [13 4 5] \tclosure(supp) = [13 0]\n", 4985808f684SSatish Balay "point = 14 \tclosure(cone) = [14 5 8] \tclosure(supp) = [14 0 1]\n", 4995808f684SSatish Balay "point = 15 \tclosure(cone) = [15 8 7] \tclosure(supp) = [15 0 2]\n", 5005808f684SSatish Balay "point = 16 \tclosure(cone) = [16 7 4] \tclosure(supp) = [16 0]\n", 5015808f684SSatish Balay "point = 17 \tclosure(cone) = [17 5 6] \tclosure(supp) = [17 1]\n", 5025808f684SSatish Balay "point = 18 \tclosure(cone) = [18 6 9] \tclosure(supp) = [18 1]\n", 5035808f684SSatish Balay "point = 19 \tclosure(cone) = [19 9 8] \tclosure(supp) = [19 1 3]\n", 5045808f684SSatish Balay "point = 20 \tclosure(cone) = [20 8 11] \tclosure(supp) = [20 2 3]\n", 5055808f684SSatish Balay "point = 21 \tclosure(cone) = [21 11 10] \tclosure(supp) = [21 2]\n", 5065808f684SSatish Balay "point = 22 \tclosure(cone) = [22 10 7] \tclosure(supp) = [22 2]\n", 5075808f684SSatish Balay "point = 23 \tclosure(cone) = [23 9 12] \tclosure(supp) = [23 3]\n", 5085808f684SSatish Balay "point = 24 \tclosure(cone) = [24 12 11] \tclosure(supp) = [24 3]\n" 5095808f684SSatish Balay ] 5105808f684SSatish Balay } 5115808f684SSatish Balay ], 5127d5fd1e4SRichard Tran Mills "source": [ 5137d5fd1e4SRichard Tran Mills "for i in range(pStart,pEnd):\n", 5147d5fd1e4SRichard Tran Mills " coneclose,orient = plex.getTransitiveClosure(i)\n", 5157d5fd1e4SRichard Tran Mills " suppclose,orient = plex.getTransitiveClosure(i,useCone=False)\n", 5167d5fd1e4SRichard Tran Mills " print(\"point =\",i,\"\\tclosure(cone) =\",coneclose,\"\\tclosure(supp) =\",suppclose)" 5177d5fd1e4SRichard Tran Mills ] 5185808f684SSatish Balay }, 5195808f684SSatish Balay { 5205808f684SSatish Balay "cell_type": "code", 5217d5fd1e4SRichard Tran Mills "execution_count": null, 5225808f684SSatish Balay "metadata": {}, 5235808f684SSatish Balay "outputs": [], 5247d5fd1e4SRichard Tran Mills "source": [] 5255808f684SSatish Balay } 5265808f684SSatish Balay ], 5277d5fd1e4SRichard Tran Mills "metadata": { 5287d5fd1e4SRichard Tran Mills "kernelspec": { 5297d5fd1e4SRichard Tran Mills "display_name": "Python 3", 5307d5fd1e4SRichard Tran Mills "language": "python", 5317d5fd1e4SRichard Tran Mills "name": "python3" 5327d5fd1e4SRichard Tran Mills }, 5337d5fd1e4SRichard Tran Mills "language_info": { 5347d5fd1e4SRichard Tran Mills "codemirror_mode": { 5357d5fd1e4SRichard Tran Mills "name": "ipython", 5367d5fd1e4SRichard Tran Mills "version": 3 5377d5fd1e4SRichard Tran Mills }, 5387d5fd1e4SRichard Tran Mills "file_extension": ".py", 5397d5fd1e4SRichard Tran Mills "mimetype": "text/x-python", 5407d5fd1e4SRichard Tran Mills "name": "python", 5417d5fd1e4SRichard Tran Mills "nbconvert_exporter": "python", 5427d5fd1e4SRichard Tran Mills "pygments_lexer": "ipython3", 5437d5fd1e4SRichard Tran Mills "version": "3.7.4" 5445808f684SSatish Balay } 5457d5fd1e4SRichard Tran Mills }, 5467d5fd1e4SRichard Tran Mills "nbformat": 4, 5477d5fd1e4SRichard Tran Mills "nbformat_minor": 1 5485808f684SSatish Balay} 549