{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Refinement Trees and Parallelization with Space-Filling Curves" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 1: Hilbert-Order Encoding of a Quadtree" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Given a domain with an obstacle (see the tutorial worksheet), we want to run a certain simulation on this domain.\n", "In order to obtain accurate results it is enough to have a fine mesh only near the boundary of the obstacle. \n", "Everywhere else the grid can be as coarse as possible.\n", "\n", "a)\n", " Use the following strategy to refine the given square domain: If a square cell contains a boundary of the obstacle, subdivide this square into four equal subsquares. \n", " Perform at most four subdivisions, in other words, the maximum depth of the corresponding quadtree is four.\n", " Sketch the resulting grid on the figure with obstacle provided in the tutorial worksheet.\n", "\n", "b)\n", " Draw a corresponding quadtree of the refined domain.\n", "\n", "c)\n", " Sequentialize the spacetree grid by using a Hilbert space-filling curve.\n", " Start with the non-terminal $H$.\n", " Use the following grammar rules for Hilbert orders on quadtrees:\n", "\n", "\n", " \n", " \n", "\n", "\n", " \n", " \n", "\n", "\n", " \n", " \n", "\n", "\n", " \n", " \n", "\n", "
 $H \\longleftarrow (A \\uparrow H \\rightarrow H \\downarrow B)$ $H \\longleftarrow \\bullet$ $A \\longleftarrow (H \\rightarrow A \\uparrow A \\leftarrow C)$ $A \\longleftarrow \\bullet$ $B \\longleftarrow (C \\leftarrow B \\downarrow B \\rightarrow H)$ $B \\longleftarrow \\bullet$ $C \\longleftarrow (B \\downarrow C \\leftarrow C \\uparrow A)$ $C \\longleftarrow \\bullet$
\n", " Hint: You might want to use the hierarchical tree representation of the refined domain or iteratively map the curve directly into the domain. \n", " Draw the resulting Hilbert curve on the in the tutorial worksheet.\n", "\n", "d)\n", " Implement a vertex-labeling algorithm to plot the iterations of the adaptive Hilbert curve. \n", " The algorithm must accept a stream of numbers, which is equivalent to the bitstream encoding of the Hilbert curve, but the single refinement bit is replaced by the number of nodes in the entire subtree.\n", " Check the results of the exercise by encoding the Hilbert curve that traverses through the domain with the obstacle by a stream of numbers and plotting the curve with your program." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### SFC python plotting routines:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "\n", "# functions to plot SFC\n", "\n", "def plotCurveDelayed(x, y, delay, title = None):\n", " px = []\n", " py = []\n", " _, ax = plt.subplots()\n", " if title is not None:\n", " plt.title(title)\n", " ax.set_xlim(min(x)-0.05, max(x)+0.05)\n", " ax.set_ylim(min(y)-0.05, max(y)+0.05)\n", " for i in xrange (len(x)):\n", " px.append(x[i])\n", " py.append(y[i])\n", " if i == 0:\n", " points, = ax.plot(px, py)\n", " else:\n", " points.set_data(px, py)\n", " plt.pause(delay)\n", "\n", "def plotLineStrip(x, y, title = None):\n", " _, ax = plt.subplots()\n", " plt.plot(x, y, linewidth = 2.0, color = 'g')\n", " if title is not None:\n", " plt.title(title)\n", " ax.set_xlim(min(x)-0.05, max(x)+0.05)\n", " ax.set_ylim(min(y)-0.05, max(y)+0.05)\n", "\n", "\n", "def plotLineStripWithCells(x, y, cellx, celly, title = None):\n", " _, ax = plt.subplots()\n", " plt.plot(cellx, celly, linewidth = 1.0, color = 'b')\n", " plt.plot(x, y, linewidth = 2.0, color = 'g')\n", " if title is not None:\n", " plt.title(title)\n", " ax.set_xlim(min(cellx)-0.05, max(cellx)+0.05)\n", " ax.set_ylim(min(celly)-0.05, max(celly)+0.05)\n", " plt.gca().set_aspect('equal', adjustable='box')\n", "\n", "def plotLineStripPartition(part_x, part_y, colors = None, title = None):\n", " _, ax = plt.subplots()\n", " if colors is None:\n", " ax.set_color_cycle(colors_default)\n", " else:\n", " ax.set_color_cycle(colors)\n", " ax.set_xlim(min(min(part_x))-0.05, max(max(part_x))+0.05)\n", " ax.set_ylim(min(min(part_y))-0.05, max(max(part_y))+0.05)\n", " for i in range(0,len(part_x)):\n", " plt.plot(part_x[i], part_y[i], linewidth = 2.0)\n", " if title is not None:\n", " plt.title(title)\n", "\n", "def plotScatterPartition(part_x, part_y, colors = None, title = None):\n", " _, ax = plt.subplots()\n", " if colors is None:\n", " colors = colors_default\n", " crssize = len(colors)\n", " ax.set_xlim(min(min(part_x))-0.05, max(max(part_x))+0.05)\n", " ax.set_ylim(min(min(part_y))-0.05, max(max(part_y))+0.05)\n", " for i in range(0,len(part_x)):\n", " plt.scatter(part_x[i], part_y[i], s=80, facecolors = 'none', \\\n", " edgecolors = colors[i%crssize])\n", " if title is not None:\n", " plt.title(title)\n", "\n", "# manually set html style colors for the color-cycle\n", "colors_default = ['#000000', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', \\\n", " '#FF00FF', '#C0C0C0', '#7FFFD4', '#FFE4C4', '#8A2BE2', '#A52A2A', \\\n", " '#6495ED', '#008B8B', '#FFD700', '#BDB76B', '#66CDAA', '#0000CD', \\\n", " '#FF4500', '#008080', '#9ACD32', '#B22222', '#000080', '#DDA0DD']\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Quadtree examples encounded by a stream of numbers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The quadtree is represented via a variant of the bitstream encoding:\n", "instead of 0/1 bits to represent whether a quadtree node is an inner\n", "node or a leaf, we will apply an integer stream, where each number\n", "represents the number of nodes contained in its respective subtree.\n", "Hence, 1 represents a leaf node, and 5 would represent a quadtree\n", "of height 2 with one inner node and four leaves. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#-----------------------------------------------------------------------------------------------\n", "# function to construct a uniformly refined tree of a given length\n", "def gen_full_tree(depth):\n", " # depth: depth of the generated spacetree\n", " if depth == 0:\n", " spacetree = \n", " else:\n", " ft = gen_full_tree(depth-1)\n", " f0 = [1+4*ft]\n", " ft = ft*4\n", " spacetree = f0 + ft\n", " return spacetree\n", "\n", "# \"Fibonnacci-SpaceTree\" (the depth decreases for the two last subtrees):\n", "def gen_fib_tree(depth):\n", " # depth: depth of the generated spacetree\n", " if depth == 0:\n", " spacetree = \n", " else:\n", " if depth == 1:\n", " dp = [depth-1]*4\n", " elif depth == 2:\n", " dp = [depth-1]*2 + [depth-2]*2\n", " else:\n", " dp = [depth-1] + [depth-2]*2 + [depth-3]\n", " fte = gen_fib_tree(dp)\n", " ft0 = fte\n", " ft = fte\n", " for k in range(1,4):\n", " fte = gen_fib_tree(dp[k])\n", " ft0 += fte\n", " ft += fte\n", " spacetree = [1+ft0]+ft\n", "\n", " return spacetree" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Auxiliary routines to find the middle of an interval or a square" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def mid4(a,b,c,d):\n", " \"\"\"Return the center of a subsquare specified\n", " by its four corners.\"\"\"\n", " return ((a+b+c+d)/4.,(a+b+c+d)/4.)\n", "\n", "def mid2(a,b):\n", " \"\"\"Rerurn the midpoint between two points,\n", " i.e. the center of the connecting edge.\"\"\"\n", "\n", " return ((a+b)/2.,(a+b)/2.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Hilbert curve class to construct a space-filling curve on a uniformly refined grid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The methods hilbertVL and hilbert implement a vertex-labeling algorithm\n", "to draw iterations of the 2D Hilbert curve. hilbertVL takes the desired recursion\n", "depth and a list of vertices as parameter; the vertices list contains the 4 coordinates\n", "of the subsquare vertices.\n", "\n", "Their respective order in the list encodes the orientation of the Hilbert\n", "curve within the subsquare. The procecure hilbert will call hilbertVL to generate\n", " Hilbert iterations of specified depth." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class HilbertSFCVertexLab(object):\n", "\n", " def __init__(self):\n", " self.points = []\n", " self.unitsquare = [(0.,0.),(0.,1,),(1.,1.),(1.,0.)]\n", "\n", " def mark(self, vertices):\n", " \"\"\"Attach a point to the class lists of points\n", " (for plotting the respective connecting polygonial line).\"\"\"\n", "\n", " self.points.append(mid4(*vertices))\n", "\n", " def getXY(self):\n", " \"\"\"Split points into x and y list for convinient plotting.\"\"\"\n", "\n", " x = [point for point in self.points]\n", " y = [point for point in self.points]\n", "\n", " return (x,y)\n", "\n", " def hilbertVL(self, depth, vertices):\n", " if (depth == 0):\n", " self.mark(vertices)\n", " else:\n", " mvall = mid4(*vertices)\n", " mv01 = mid2(vertices,vertices)\n", " mv03 = mid2(vertices,vertices)\n", " mv12 = mid2(vertices,vertices)\n", " mv23 = mid2(vertices,vertices)\n", "\n", " self.hilbertVL(depth-1, [vertices, mv03, mvall, mv01])\n", " self.hilbertVL(depth-1, [mv01, vertices, mv12, mvall])\n", " self.hilbertVL(depth-1, [mvall, mv12, vertices, mv23])\n", " self.hilbertVL(depth-1, [mv23, mvall, mv03, vertices])\n", "\n", " def hilbert(self, depth):\n", " self.points = []\n", " self.hilbertVL(depth,self.unitsquare)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Hilbert curve class to construct an adaptive space-filling curve" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Method hilbertChilds is equivalent to method hilbertVL,\n", "but generates an adaptive Hilbert order on the quadtree encoded\n", "by the list vertices." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class HilbertSFCVertexLabAdp(HilbertSFCVertexLab):\n", "\n", " def __init__(self):\n", " super(HilbertSFCVertexLabAdp,self).__init__()\n", " self.spacetree = \n", " self.stptr = -1\n", " self.cubes = []\n", " \n", " def markCube(self, v1, v2):\n", " \"\"\"Attach coordinates of a cube to class list of cubes.\"\"\"\n", "\n", " cube = [v1, (v1,v2), v2, (v2,v1), v1, (v1,v2), v2]\n", " self.cubes.extend(cube)\n", "\n", " def getCubeXY(self):\n", " \"\"\"Split cube coordinates into x and y list for convinient plotting.\"\"\"\n", "\n", " x = [cube for cube in self.cubes]\n", " y = [cube for cube in self.cubes]\n", " \n", " return (x,y)\n", "\n", " def hilbertChilds(self, vertices):\n", " pass\n", " # TODO: Exercise 1\n", " \n", " def hilbert(self, spacetree):\n", " self.points = []\n", " self.cubes = []\n", " self.stptr = -1\n", " self.spacetree = spacetree\n", " self.hilbertChilds(self.unitsquare)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Demo" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ValueError", "evalue": "min() arg is an empty sequence", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mplotCurveDelayed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdelay\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mplotLineStripWithCells\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcellX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcellY\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mplotLineStripWithCells\u001b[0;34m(x, y, cellx, celly, title)\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtitle\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 38\u001b[0;31m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_xlim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcellx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcellx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 39\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_ylim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcelly\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcelly\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_aspect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'equal'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0madjustable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'box'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: min() arg is an empty sequence" ] } ], "source": [ "# set delay for animation\n", "delay = 0.0\n", "\n", "hsfc_adp = HilbertSFCVertexLabAdp()\n", "hsfc_adp.hilbert(gen_fib_tree(9))\n", "X, Y = hsfc_adp.getXY()\n", "cellX, cellY = hsfc_adp.getCubeXY()\n", "if delay > 0.0:\n", " plotCurveDelayed(X, Y, delay)\n", "else:\n", " plotLineStripWithCells(X, Y, cellX, cellY)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 2: Parallelization with Space-Filling Curves" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We want to traverse an adaptive grid in the Hilbert curve order in a parallel setting.\n", "Consider the following two situations and complete the tasks:\n", "\n", "a)\n", " Assume that we use a shared-memory environment and several threads can process the unknowns on an adaptive grid.\n", " We can keep only one copy of the refinement structure for all threads in a vertex labeled stream of numbers format, but we would like the threads to be able to traverse only a certain part of the quadtree and skip all other parts.\n", " Extend the program from the previous exercise by adding a method that allows to traverse only a part of the tree specified by given start and end node indices.\n", "\n", "b)\n", " In a distributed-memory setting usually only a separate local grid is stored by each process.\n", " In this case, we can keep the grid traversal simple by retaining the global grid representation, but coarsening the non-local partitions as far as possible.\n", " Partition the domain represented in the tutorial worksheet for four processes by dividing the Hilbert space-filling curve into equal parts.\n", " Sketch all four grid representations for each process with corresponding space-filling curves and local quadtree structures." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Hilbert curve class to construct only a certain part of an adaptive space-filling curve" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Method hilbertPartition is equivalent to function hilbertChilds,\n", "but generates only one partition of an adaptive Hilbert order, given\n", "by the first and last index of the respective subsquares." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class HilbertSFCVertexLabAdpPart(HilbertSFCVertexLabAdp):\n", "\n", " def __init__(self):\n", " super(HilbertSFCVertexLabAdp,self).__init__()\n", " \n", " def hilbertPartition(self, vertices):\n", " pass\n", " # TODO: Exercise 2\n", "\n", " def hilbert(self,spacetree,first,last):\n", " self.points = []\n", " self.cubes = []\n", " self.stptr = -1\n", " self.spacetree = spacetree\n", " self.first = first\n", " self.last =last\n", " self.hilbertPartition(self.unitsquare)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Demo" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ValueError", "evalue": "min() arg is an empty sequence", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mplotCurveDelayed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdelay\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0mplotLineStripWithCells\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcellX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcellY\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mplotLineStripWithCells\u001b[0;34m(x, y, cellx, celly, title)\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtitle\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 38\u001b[0;31m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_xlim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcellx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcellx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 39\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_ylim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcelly\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcelly\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_aspect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'equal'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0madjustable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'box'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: min() arg is an empty sequence" ] } ], "source": [ "hsfc_adp_part = HilbertSFCVertexLabAdpPart()\n", "\n", "hsfc_adp_part.hilbert(gen_fib_tree(5),20,57)\n", "X, Y = hsfc_adp_part.getXY()\n", "cellX, cellY = hsfc_adp_part.getCubeXY()\n", "if delay > 0.0:\n", " plotCurveDelayed(X, Y, delay)\n", "else:\n", " plotLineStripWithCells(X, Y, cellX, cellY)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 0 }