diff --git a/SWESimulators/Common.py b/SWESimulators/Common.py index 3370dbc..e0483a0 100644 --- a/SWESimulators/Common.py +++ b/SWESimulators/Common.py @@ -2,6 +2,7 @@ import os import numpy as np import time +import re import pycuda.compiler as cuda_compiler import pycuda.gpuarray @@ -36,39 +37,72 @@ class CudaContext(object): print("=== WARNING ===") else: self.cuda_context = self.cuda_device.make_context(flags=cuda.ctx_flags.SCHED_AUTO) + + if (self.verbose): + print("Created context <" + str(self.cuda_context.handle) + ">") def __del__(self, *args): if self.verbose: - print("Cleaning up CUDA context") + print("Cleaning up CUDA context <" + str(self.cuda_context.handle) + ">") - self.cuda_context.detach() - cuda.Context.pop() + # Loop over all contexts in stack, and remove "this" + other_contexts = [] + while (cuda.Context.get_current() != None): + context = cuda.Context.get_current() + if (self.verbose): + if (context.handle != self.cuda_context.handle): + print(" `-> <" + str(self.cuda_context.handle) + "> Popping context <" + str(context.handle) + "> which we do not own") + other_contexts = [context] + other_contexts + cuda.Context.pop() + else: + print(" `-> <" + str(self.cuda_context.handle) + "> Popping context <" + str(context.handle) + "> (ourselves)") + cuda.Context.pop() + # Add all the contexts we popped that were not our own + for context in other_contexts: + if (self.verbose): + print(" `-> <" + str(self.cuda_context.handle) + "> Pushing <" + str(context.handle) + ">") + cuda.Context.push(context) + if (self.verbose): + print(" `-> <" + str(self.cuda_context.handle) + "> Detaching context") + self.cuda_context.detach() + + + """ Reads a text file and creates an OpenCL kernel from that """ def get_kernel(self, kernel_filename, block_width, block_height): # Generate a kernel ID for our cache module_path = os.path.dirname(os.path.realpath(__file__)) - fullpath = os.path.join(module_path, kernel_filename) - kernel_date = os.path.getmtime(fullpath) - with open(fullpath, "r") as kernel_file: - kernel_hash = hash(kernel_file.read()) - kernel_id = kernel_filename + ":" + str(kernel_hash) + ":" + str(kernel_date) + + kernel_hash = "" + + # Loop over file and includes, and check if something has changed + files = [kernel_filename] + while len(files): + filename = os.path.join(module_path, files.pop()) + modified = os.path.getmtime(filename) + with open(filename, "r") as file: + file_str = file.read() + file_hash = filename + "_" + str(hash(file_str)) + ":" + str(modified) + "--" + includes = re.findall('^\W*#include\W+(.+?)\W*$', file_str, re.M) + files = files + includes #WARNING FIXME This will not work with circular includes + + kernel_hash = kernel_hash + file_hash - # Simple caching to keep keep from recompiling kernels - if (kernel_id not in self.kernels.keys()): + # Recompile kernel if file or includes have changed + if (kernel_hash not in self.kernels.keys()): #Create define string define_string = "#define block_width " + str(block_width) + "\n" define_string += "#define block_height " + str(block_height) + "\n\n" + kernel_string = define_string + '#include "' + os.path.join(module_path, kernel_filename) + '"' + self.kernels[kernel_hash] = cuda_compiler.SourceModule(kernel_string, include_dirs=[module_path]) - kernel_string = define_string + '#include "' + fullpath + '"' - self.kernels[kernel_id] = cuda_compiler.SourceModule(kernel_string, include_dirs=[module_path]) - - return self.kernels[kernel_id] + return self.kernels[kernel_hash] """ Clears the kernel cache (useful for debugging & development) diff --git a/SWESimulators/KP07.py b/SWESimulators/KP07.py index cbdf867..1922a56 100644 --- a/SWESimulators/KP07.py +++ b/SWESimulators/KP07.py @@ -96,8 +96,8 @@ class KP07: self.dy = np.float32(dy) self.dt = np.float32(dt) self.g = np.float32(g) - self.r = np.float32(r) self.theta = np.float32(theta) + self.r = np.float32(r) self.use_rk2 = use_rk2 #Initialize time diff --git a/WAFExp.ipynb b/WAFExp.ipynb new file mode 100644 index 0000000..7f8f2b3 --- /dev/null +++ b/WAFExp.ipynb @@ -0,0 +1,3083 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#Lets have matplotlib \"inline\"\n", + "%matplotlib notebook\n", + "\n", + "#Import packages we need\n", + "import numpy as np\n", + "import os\n", + "import subprocess\n", + "from matplotlib import animation, rc\n", + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#Misc plotting setup\n", + "def setBwStyles(ax):\n", + " from cycler import cycler\n", + "\n", + " ax.set_prop_cycle( cycler('marker', ['.', 'x', 4, '+', '*', '1', 5]) +\n", + " cycler('linestyle', ['-.', '--', ':', '-.', '--', ':', '-.']) +\n", + " #cycler('markersize', [5, 5, 5, 5, 5, 5]) +\n", + " cycler('color', ['k', 'k', 'k', 'k', 'k', 'k', 'k']) ) \n", + "\n", + "#Set large figure sizes\n", + "#plt.rcParams['figure.figsize'] = [12, 8]\n", + "plt.rcParams['figure.dpi'] = 100\n", + "plt.rcParams['animation.html'] = 'html5'\n", + "#plt.rcParams['legend.markerscale'] = 1.0\n", + "#plt.rcParams['lines.markersize'] = 6\n", + "plt.rcParams['lines.markeredgewidth'] = 1.5\n", + "#plt.rcParams['savefig.dpi'] = 400" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nref_x, ref_h, _ = gen_reference(512)\\nplt.plot(ref_x, ref_h, \\'-\\', label=\\'Reference\\')\\nplt.title(\"Reference data\")\\nplt.legend()\\nplt.show()\\n'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def gen_reference(nx):\n", + " csv_filename = 'shock1d_ref_nx=' + str(nx) + '.csv'\n", + "\n", + " #If we do not have the data, generate it \n", + " if (not os.path.isfile(csv_filename)):\n", + " print(\"Generating new reference!\")\n", + " swashes_path = r'C:\\Users\\anbro\\Documents\\programs\\SWASHES-1.03.00_win\\bin\\swashes_win.exe'\n", + "\n", + " swashes_args = [\\\n", + " '1', # 1D problems \\\n", + " '3', # Dam breaks \\\n", + " '1', # Domain 1 \\\n", + " '1', # Wet domain no friction\n", + " str(nx) #Number of cells X\n", + " ]\n", + "\n", + " with open(csv_filename, 'w') as csv_file:\n", + " p = subprocess.check_call([swashes_path] + swashes_args, stdout=csv_file)\n", + "\n", + " reference = np.genfromtxt(csv_filename, comments='#', delimiter='\\t', skip_header=0, usecols=(0, 1, 2))\n", + " x, h, u = reference[:, 0], reference[:, 1], reference[:, 2]\n", + " return x, h, h*u\n", + "\n", + "\"\"\"\n", + "ref_x, ref_h, _ = gen_reference(512)\n", + "plt.plot(ref_x, ref_h, '-', label='Reference')\n", + "plt.title(\"Reference data\")\n", + "plt.legend()\n", + "plt.show()\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nr = np.linspace(-1.0, 2.0, 10)\\nc = -15*np.ones_like(r)\\n\\nx = r\\ny = list(map(WAF_minmod, r, c))\\n\\nplt.figure()\\nplt.plot(x, y)\\nplt.title(\"WAF minmod limiter\")\\nplt.show()\\n'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def WAF_minmod(r_, c_):\n", + " return 1.0 - (1.0 - abs(c_)) * max(0.0, min(1.0, r_));\n", + "\n", + "\"\"\"\n", + "r = np.linspace(-1.0, 2.0, 10)\n", + "c = -15*np.ones_like(r)\n", + "\n", + "x = r\n", + "y = list(map(WAF_minmod, r, c))\n", + "\n", + "plt.figure()\n", + "plt.plot(x, y)\n", + "plt.title(\"WAF minmod limiter\")\n", + "plt.show()\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nref_x, ref_h, ref_hu = gen_reference(512)\\nF = np.array(list(map(F_func_helper, ref_h, ref_hu)))\\n\\nfig, ax1 = plt.subplots()\\nplt.ylim([0, 0.01])\\nax2 = ax1.twinx()\\n\\nax1.plot(ref_x, ref_h, \\'-\\', label=\\'Reference\\')\\n\\nax2.plot(ref_x, F[:,0], \\':\\', label=\\'F_0\\')\\nax2.plot(ref_x, F[:,1], \\'.-\\', label=\\'F_1\\')\\nax2.plot(ref_x, F[:,2], \\'--\\', label=\\'F_2\\')\\n\\nplt.title(\"Flux function for shallow water\")\\nplt.legend()\\n'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def F_func(Q, g):\n", + " F = np.zeros(3)\n", + "\n", + " F[0] = Q[1]; #hu\n", + " F[1] = Q[1]*Q[1] / Q[0] + 0.5*g*Q[0]*Q[0]; #hu*hu/h + 0.5f*g*h*h;\n", + " F[2] = Q[1]*Q[2] / Q[0]; #hu*hv/h;\n", + "\n", + " return F;\n", + "\n", + "def F_func_helper(h, hu):\n", + " return F_func(np.array([h, hu, 0.0]), 9.81)\n", + "\n", + "\"\"\"\n", + "ref_x, ref_h, ref_hu = gen_reference(512)\n", + "F = np.array(list(map(F_func_helper, ref_h, ref_hu)))\n", + "\n", + "fig, ax1 = plt.subplots()\n", + "plt.ylim([0, 0.01])\n", + "ax2 = ax1.twinx()\n", + "\n", + "ax1.plot(ref_x, ref_h, '-', label='Reference')\n", + "\n", + "ax2.plot(ref_x, F[:,0], ':', label='F_0')\n", + "ax2.plot(ref_x, F[:,1], '.-', label='F_1')\n", + "ax2.plot(ref_x, F[:,2], '--', label='F_2')\n", + "\n", + "plt.title(\"Flux function for shallow water\")\n", + "plt.legend()\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nref_x, ref_h, ref_hu = gen_reference(512)\\nF = WAF_1D_flux_helper(ref_h, ref_hu, 9.81, 0.1, 0.01)\\n\\nfig, ax1 = plt.subplots()\\nplt.ylim([0, 0.01])\\nax2 = ax1.twinx()\\n\\nax1.plot(ref_x, ref_h, \\'--\\', label=\\'Reference\\')\\n\\nfor i in range(F.shape[1]):\\n ax2.plot(ref_x[2:-1], F[:,i], label=\\'F_\\' + str(i))\\n\\nplt.title(\"WAF flux for shallow water\")\\nplt.legend()\\n'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def WAF_1D_flux(Q_l2, Q_l1, Q_r1, Q_r2, g_, dx_, dt_): \n", + " h_l = Q_l1[0];\n", + " h_r = Q_r1[0];\n", + " \n", + " h_l2 = Q_l2[0];\n", + " h_r2 = Q_r2[0];\n", + " \n", + " # Calculate velocities\n", + " u_l = Q_l1[1] / h_l;\n", + " u_r = Q_r1[1] / h_r;\n", + " \n", + " v_l = Q_l1[2] / h_l;\n", + " v_r = Q_r1[2] / h_r;\n", + " \n", + " v_l2 = Q_l2[2] / h_l2;\n", + " v_r2 = Q_r2[2] / h_r2;\n", + " \n", + " # Estimate the potential wave speeds\n", + " c_l = np.sqrt(g_*h_l);\n", + " c_r = np.sqrt(g_*h_r);\n", + " \n", + " # Compute h in the \"star region\", h^dagger\n", + " h_dag = 0.5 * (h_l+h_r) - 0.25 * (u_r-u_l)*(h_l+h_r)/(c_l+c_r);\n", + " \n", + " q_l_tmp = np.sqrt(0.5 * ( (h_dag+h_l)*h_dag / (h_l*h_l) ) );\n", + " q_r_tmp = np.sqrt(0.5 * ( (h_dag+h_r)*h_dag / (h_r*h_r) ) );\n", + " \n", + " q_l = q_l_tmp if (h_dag > h_l) else 1.0;\n", + " q_r = q_r_tmp if (h_dag > h_r) else 1.0;\n", + " \n", + " # Compute wave speed estimates\n", + " S_l = u_l - c_l*q_l; #FIXME: Correct wave speed estimate?\n", + " S_r = u_r + c_r*q_r;\n", + " S_star = ( S_l*h_r*(u_r - S_r) - S_r*h_l*(u_l - S_l) ) / ( h_r*(u_r - S_r) - h_l*(u_l - S_l) );\n", + " \n", + " Q_star_l = h_l * (S_l - u_l) / (S_l - S_star) * np.array([1.0, S_star, v_l]);\n", + " Q_star_r = h_r * (S_r - u_r) / (S_r - S_star) * np.array([1.0, S_star, v_r]);\n", + " \n", + " # Estimate the fluxes in the four regions\n", + " F_1 = F_func(Q_l1, g_);\n", + " F_4 = F_func(Q_r1, g_);\n", + " \n", + " F_2 = F_1 + S_l*(Q_star_l - Q_l1);\n", + " F_3 = F_4 + S_r*(Q_star_r - Q_r1);\n", + " \n", + " # Compute the courant numbers for the waves\n", + " c_1 = S_l * dt_ / dx_;\n", + " c_2 = S_star * dt_ / dx_;\n", + " c_3 = S_r * dt_ / dx_;\n", + " \n", + " # Compute the \"upwind change\" vectors for the i-3/2 and i+3/2 interfaces\n", + " \n", + " \"\"\"\n", + " rh_denom = float(h_r) - float(h_l)\n", + " \n", + " rh_m = 2.0\n", + " rh_p = 2.0\n", + " \n", + " if (abs(rh_denom) > 0.0):\n", + " rh_m = (float(h_l) - float(h_l2)) / rh_denom\n", + " rh_p = (float(h_r2) - float(h_r)) / rh_denom\n", + " else:\n", + " rh_m = rh_m * np.sign(float(h_l) - float(h_l2))\n", + " rh_p = rh_p * np.sign(float(h_r2) - float(h_r))\n", + " \n", + " rv_denom = float(v_r) - float(v_l)\n", + " \n", + " rv_m = 10**10\n", + " rv_p = 10**10\n", + " \n", + " if (abs(rv_denom) > 0.0):\n", + " rv_m = (float(v_l) - float(v_l2)) / rv_denom\n", + " rv_p = (float(v_r2) - float(v_r)) / rv_denom\n", + " else:\n", + " rv_m = rv_m * np.sign(float(v_l) - float(v_l2))\n", + " rv_p = rv_p * np.sign(float(v_r2) - float(v_r))\n", + " \"\"\"\n", + " \n", + " \n", + " \n", + " \"\"\"\n", + " rh_m = (h_l - h_l2) / (h_r - h_l) if (h_r != h_l) else 10**10*np.sign(h_l-h_l2);\n", + " rh_p = (h_r2 - h_r) / (h_r - h_l) if (h_r != h_l) else 10**10*np.sign(h_r2-h_r);\n", + " \n", + " rv_m = (v_l - v_l2) / (v_r - v_l) if (v_r != v_l) else 10**10*np.sign(v_l-v_l2);\n", + " rv_p = (v_r2 - v_r) / (v_r - v_l) if (v_r != v_l) else 10**10*np.sign(v_r2-v_r);\n", + " \"\"\"\n", + " \n", + " \n", + " eps = 1e-10\n", + " orig_denom = h_r - h_l\n", + " denom = orig_denom\n", + " if (h_r == h_l):\n", + " if (np.abs(h_l - h_l2) > eps):\n", + " rh_m = 10.0*np.sign(h_l - h_l2)\n", + " else:\n", + " rh_m = 0.0\n", + " if (np.abs(h_r2 - h_r) > eps):\n", + " rh_p = 10.0*np.sign(h_r2 - h_r)\n", + " else:\n", + " rh_p = 0.0\n", + " elif (np.abs(h_r - h_l) < eps):\n", + " # np.maximum(np.minimum(x*x/(2*eps)+0.5*eps, eps), x)\n", + " denom = (np.sign(orig_denom)*max(min(orig_denom*orig_denom/(2*eps)+0.5*eps, eps), abs(orig_denom)))\n", + " rh_m = (h_l - h_l2) / denom\n", + " rh_p = (h_r2 - h_r) / denom\n", + " else:\n", + " rh_m = (h_l - h_l2) / (h_r - h_l)\n", + " rh_p = (h_r2 - h_r) / (h_r - h_l)\n", + " \n", + " \n", + " \n", + " rv_m = -10**10 #(v_l - v_l2) / (v_r - v_l) if (v_r != v_l) else 10**10*np.sign(v_l-v_l2);\n", + " rv_p = -10**10 #(v_r2 - v_r) / (v_r - v_l) if (v_r != v_l) else 10**10*np.sign(v_r2-v_r);\n", + " \n", + " \"\"\"\n", + " rh_m = (h_l - h_l2) / (h_r - h_l);\n", + " rh_p = (h_r2 - h_r) / (h_r - h_l); \n", + " \n", + " rv_m = (v_l - v_l2) / (v_r - v_l);\n", + " rv_p = (v_r2 - v_r) / (v_r - v_l);\n", + " \"\"\"\n", + " \n", + " # Compute the r parameters for the flux limiter\n", + " rh_1 = rh_m if (c_1 > 0.0) else rh_p; \n", + " rv_1 = rv_m if (c_1 > 0.0) else rv_p; \n", + " \n", + " rh_2 = rh_m if (c_2 > 0.0) else rh_p; \n", + " rv_2 = rv_m if (c_2 > 0.0) else rv_p; \n", + " \n", + " rh_3 = rh_m if (c_3 > 0.0) else rh_p;\n", + " rv_3 = rv_m if (c_3 > 0.0) else rv_p;\n", + " \n", + " # Compute the limiter\n", + " # We use h for the nonlinear waves, and v for the middle shear wave \n", + " A_1 = np.sign(c_1) * WAF_minmod(rh_1, c_1);\n", + " A_2 = np.sign(c_2) * WAF_minmod(rv_2, c_2); #Middle shear wave \n", + " A_3 = np.sign(c_3) * WAF_minmod(rh_3, c_3); \n", + " \n", + " # Average the fluxes\n", + " flux = 0.5*( F_1 + F_4 ) \\\n", + " - 0.5*( A_1 * (F_2 - F_1) \\\n", + " + A_2 * (F_3 - F_2) \\\n", + " + A_3 * (F_4 - F_3) );\n", + " \n", + " flux_nolimit = 0.5*( F_1 + F_4 ) \\\n", + " - 0.5*( c_1 * (F_2 - F_1) \\\n", + " + c_2 * (F_3 - F_2) \\\n", + " + c_3 * (F_4 - F_3) );\n", + " \n", + " flux_hll = np.array([0.0, 0.0, 0.0])\n", + " if (S_l >= 0.0):\n", + " flux_hll = F_1;\n", + " elif (S_r <= 0.0):\n", + " flux_hll = F_4;\n", + " elif (S_l <= 0.0 and 0.0 <=S_star):\n", + " flux_hll = F_1 + S_l*(Q_star_l - Q_l1);\n", + " elif (S_star <= 0.0 and 0.0 <=S_r):\n", + " flux_hll = F_4 + S_r*(Q_star_r - Q_r1);\n", + "\n", + " #return flux\n", + "\n", + " #return [rh_1, rv_2, rh_3];\n", + " #return [A_1, A_2, A_3]\n", + " #return [A_1 + A_2 + A_3]\n", + " #return [c_1 + c_2 + c_3]\n", + "\n", + " #return [A_1 + A_2 + A_3, \\\n", + " #c_1 + c_2 + c_3]\n", + " #return [A_1, A_2, A_3, c_1, c_2, c_3]\n", + " \n", + " return [flux, flux_nolimit]\n", + " \n", + " #return [rh_1, A_1, c_1]\n", + " #return [A_1, A_2, A_3]\n", + " #return [(h_r2 - h_r)/(h_r - h_l), rh_p]\n", + " #return [denom, orig_denom]\n", + " \n", + " #i = 2\n", + " #return [F_1[i], F_2[i], F_3[i], F_4[i]]\n", + "\n", + "\n", + "def WAF_1D_flux_helper(h, hu, g, dx, dt):\n", + " \n", + " hv = np.zeros_like(h)\n", + " Q = np.vstack([h, hu, hv]).T\n", + " \n", + " Q_l2 = Q[0:-3,:]\n", + " Q_l1 = Q[1:-2,:]\n", + " Q_r1 = Q[2:-1,:]\n", + " Q_r2 = Q[3:,:]\n", + " \n", + " g = np.ones(Q_l2.shape[0])*g\n", + " dx = np.ones(Q_l2.shape[0])*dx\n", + " dt = np.ones(Q_l2.shape[0])*dt\n", + " \n", + " return np.array(list(map(WAF_1D_flux, Q_l2, Q_l1, Q_r1, Q_r2, g, dx, dt)))\n", + "\n", + "\"\"\"\n", + "ref_x, ref_h, ref_hu = gen_reference(512)\n", + "F = WAF_1D_flux_helper(ref_h, ref_hu, 9.81, 0.1, 0.01)\n", + "\n", + "fig, ax1 = plt.subplots()\n", + "plt.ylim([0, 0.01])\n", + "ax2 = ax1.twinx()\n", + "\n", + "ax1.plot(ref_x, ref_h, '--', label='Reference')\n", + "\n", + "for i in range(F.shape[1]):\n", + " ax2.plot(ref_x[2:-1], F[:,i], label='F_' + str(i))\n", + "\n", + "plt.title(\"WAF flux for shallow water\")\n", + "plt.legend()\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nfig = plt.figure()\\nplt.ylim([0, 0.01])\\n\\nref_x, ref_h, ref_hu = gen_reference(128)\\nplt.plot(ref_x, ref_h, \\'-\\')\\n\\nfor i in range(50):\\n h, hu = WAF_step(ref_h, ref_hu, 9.81, 0.1, 0.1)\\nplt.plot(ref_x, h, \\'--\\')\\n\\nplt.title(\"WAF for shallow water\")\\nplt.legend()\\n'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def WAF_step(h, hu, g, dx, dt):\n", + " F = WAF_1D_flux_helper(h, hu, g, dx, dt)\n", + " \n", + " h[2:-2] = h[2:-2] + (F[0:-1,0] - F[1:,0]) * dt / dx;\n", + " hu[2:-2] = hu[2:-2] + (F[0:-1,1] - F[1:,1]) * dt / dx;\n", + " \n", + " return [h, hu]\n", + " \n", + "\"\"\"\n", + "fig = plt.figure()\n", + "plt.ylim([0, 0.01])\n", + "\n", + "ref_x, ref_h, ref_hu = gen_reference(128)\n", + "plt.plot(ref_x, ref_h, '-')\n", + "\n", + "for i in range(50):\n", + " h, hu = WAF_step(ref_h, ref_hu, 9.81, 0.1, 0.1)\n", + "plt.plot(ref_x, h, '--')\n", + "\n", + "plt.title(\"WAF for shallow water\")\n", + "plt.legend()\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def gen_test_data(nx, ny, g, num_ghost_cells):\n", + " width = 100.0\n", + " height = 100.0\n", + " dx = width / float(nx)\n", + " dy = height / float(ny)\n", + "\n", + " x_center = dx*nx/2.0\n", + " y_center = dy*ny/2.0\n", + " \n", + " h = np.zeros((ny+2*num_ghost_cells, nx+2*num_ghost_cells)); \n", + " hu = np.zeros((ny+2*num_ghost_cells, nx+2*num_ghost_cells));\n", + " hv = np.zeros((ny+2*num_ghost_cells, nx+2*num_ghost_cells));\n", + "\n", + " #Create a gaussian \"dam break\" that will not form shocks\n", + " size = width / 5.0\n", + " dt = 10**10\n", + " for j in range(-num_ghost_cells, ny+num_ghost_cells):\n", + " for i in range(-num_ghost_cells, nx+num_ghost_cells):\n", + " x = dx*(i+0.5) - x_center\n", + " y = dy*(j+0.5) - y_center\n", + " \n", + " h[j+num_ghost_cells, i+num_ghost_cells] = 0.5 + 0.1*np.exp(-(x**2/size))\n", + " hu[j+num_ghost_cells, i+num_ghost_cells] = 0.1*np.exp(-(x**2/size))\n", + " \n", + " max_h_estimate = 0.6\n", + " max_u_estimate = 0.1*2.0\n", + " dt = min(dx, dy) / (max_u_estimate + np.sqrt(g*max_h_estimate))\n", + " \n", + " return h, hu, hv, dx, dy, dt" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Step 1/56\n", + "Step 2/56\n", + "Step 3/56\n", + "Step 4/56\n", + "Step 5/56\n", + "Step 6/56\n", + "Step 7/56\n", + "Step 8/56\n", + "Step 9/56\n", + "Step 10/56\n", + "Step 11/56\n", + "Step 12/56\n", + "Step 13/56\n", + "Step 14/56\n", + "Step 15/56\n", + "Step 16/56\n", + "Step 17/56\n", + "Step 18/56\n", + "Step 19/56\n", + "Step 20/56\n", + "Step 21/56\n", + "Step 22/56\n", + "Step 23/56\n", + "Step 24/56\n", + "Step 25/56\n", + "Step 26/56\n", + "Step 27/56\n", + "Step 28/56\n", + "Step 29/56\n", + "Step 30/56\n", + "Step 31/56\n", + "Step 32/56\n", + "Step 33/56\n", + "Step 34/56\n", + "Step 35/56\n", + "Step 36/56\n", + "Step 37/56\n", + "Step 38/56\n", + "Step 39/56\n", + "Step 40/56\n", + "Step 41/56\n", + "Step 42/56\n", + "Step 43/56\n", + "Step 44/56\n", + "Step 45/56\n", + "Step 46/56\n", + "Step 47/56\n", + "Step 48/56\n", + "Step 49/56\n", + "Step 50/56\n", + "Step 51/56\n", + "Step 52/56\n", + "Step 53/56\n", + "Step 54/56\n", + "Step 55/56\n", + "Step 56/56\n" + ] + } + ], + "source": [ + "nx=1025\n", + "g = 9.81\n", + "h0, hu0, hv0, dx, dy, dt = gen_test_data(nx, 1, 9.81, 0)\n", + "\n", + "h = h0.ravel()\n", + "hu = hu0.ravel()\n", + "x = np.linspace(0.0, nx*dx, nx)\n", + "\n", + "dt = dt*0.95\n", + "\n", + "timesteps = int(2.0/dt)\n", + "for i in range(timesteps):\n", + " print(\"Step \" + str(i+1) + \"/\" + str(timesteps))\n", + " WAF_step(h, hu, g, dx, dt) " + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F = WAF_1D_flux_helper(h, hu, g, dx, dt)\n", + "plt.figure()\n", + "for i in range(F.shape[1]):\n", + " plt.plot(x[2:-1], F[:,i], marker=' ', label='F_' + str(i))\n", + "#plt.ylim(-10, 10)\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('