{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from numpy import zeros\n",
    "import numpy.polynomial.chebyshev as C\n",
    "from scipy.linalg import solve\n",
    "\n",
    "def laplace_solve(x, f, k=0):\n",
    "    \"\"\"\n",
    "    Laplacian solve with mixed derivatives on boundary of the form\n",
    "    \n",
    "    u_z + k u = 0\n",
    "    \n",
    "    this is used for the vorticity inversion in Xing\n",
    "    \"\"\"\n",
    "    \n",
    "    a = 0\n",
    "    b = 0\n",
    "    \n",
    "    n = x.shape[0]-1\n",
    "\n",
    "    # x does not need to be (-1,1)\n",
    "    scal = 2/(x.max()-x.min()) \n",
    "    xx = (x-x.min())/(x.max()-x.min()) * 2 -1\n",
    "\n",
    "    # Identity matrix   \n",
    "    I = np.eye(n+1)\n",
    "\n",
    "    # derivative matrices (n+1)x(n-1)\n",
    "    D = C.chebder(I,1, scl=scal)\n",
    "    D2 = C.chebder(I,2, scl=scal)\n",
    "\n",
    "    # Chebshev Vandermonde matrix\n",
    "    V = C.chebvander(xx,n)\n",
    "\n",
    "\n",
    "    # Transform forcing function to mode space\n",
    "    fhat = solve(V,f)\n",
    "\n",
    "    # Boundary operators for last two rows (tau conditions)\n",
    "    # First and last rows of Vandermonde contain the boundary\n",
    "    # values of the Chebyshev polynomials  \n",
    "    B = zeros((2, V.shape[1]))\n",
    "    B[0,:] = V[0,:]\n",
    "    B[1,:] = k* V[-1,:] + C.chebval(1.0, D)\n",
    "\n",
    "    # Left-hand-side\n",
    "    A = -D2\n",
    "    L = np.vstack((A,B))\n",
    "\n",
    "    # Insert boundary values into the last two elements of \n",
    "    # the right-hand-side\n",
    "    fhat[-2] = a\n",
    "    fhat[-1] = b\n",
    "\n",
    "    # Compute expansion coefficients of the solution\n",
    "    yhat = solve(L,fhat)\n",
    "\n",
    "    # Transform solution to point space\n",
    "    y = V.dot(yhat)\n",
    "    \n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10fe04668>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "# Chebyshev-Gauss-Lobatto points\n",
    "x= np.linspace(-1,1,30)\n",
    "# Forcing function \n",
    "f = 1 + np.tanh(4*x)\n",
    "f = np.sin(np.pi*x)\n",
    "y=laplace_solve(x,f, k=1)\n",
    "\n",
    "# Plot solution\n",
    "plt.plot(x,y,lw=2)\n",
    "plt.show()"
   ]
  }
 ],
 "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.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}