{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![logo](JFM-notebooks-logo.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Spectral analysis of the laminar flow and the lower branch traveling wave\n", "\n", "In this notebook we present calculations related to the spectrum of the two fixed point solutions, the lower branch traveling wave and the laminar flow. \n", "The eigenvalues are obtained using the Newton-Krylov algorithm built into ```Openpipeflow``` (developed by Ashley Willis, https://openpipeflow.org/).\n", "\n", "- We show the leading eigenvalues of the lower branch traveling wave and check that the nonresonance conditions required by results of Haller et al. 2023 hold.\n", "\n", "- We show the calculations necessary to explicitly compute the analytic (primary) slow SSM of the laminar flow" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Check for resonances in the spectrum of the lower branch traveling wave" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "eig2LB = np.loadtxt('data/arnoldi.dat', skiprows = 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The existence results for the mixed-mode SSM apply if Sternberg's linearization theorem applies. \n", "Let us denote the eigenvalues as $\\lambda_i$ and ordering them according to descending real part. We then require that there is no resonance among eigenvalues, i.e\n", "\n", "$$\n", "\\lambda_j \\neq \\sum_{i} m_i \\lambda_i \\quad \\sum_i m_i \\geq 2\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We select the leading $15$ eigenvalues, but this corresponds to $24$ eigenvalues in total, due to the complex-conjugate pairs. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "ms = np.arange(0, 5, 1)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "eigenvalues = eig2LB[np.abs(eig2LB[:,1])>0.001, 1] + 1j*eig2LB[np.abs(eig2LB[:,1])>0.001,2]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "eigenvalues = np.unique(np.concatenate((eigenvalues, np.conjugate(eigenvalues))))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "sort_ind = np.argsort(-np.real(eigenvalues), axis=0)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "eigenvalues = np.take_along_axis(eigenvalues, sort_ind, axis = 0)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from sklearn.preprocessing import PolynomialFeatures" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "polyfeat = PolynomialFeatures(degree = 6)\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
PolynomialFeatures(degree=6)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "PolynomialFeatures(degree=6)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polyfeat.fit(np.ones(eigenvalues.shape).reshape(1,-1)) # we use PolynomialFeatures to get all linear combinations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We create an array that enumerates all possible integer linear combinations of the eigenvalues up to order 5. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "poww = polyfeat.powers_" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(593775, 24)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "poww.shape" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [], "source": [ "lincombs = []" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [], "source": [ "for i in range(poww.shape[0]):\n", " if np.sum(poww[i,:]>1):\n", " summ = 0.\n", " for j in range(poww.shape[1]):\n", " summ = summ + poww[i,j]*eigenvalues[j]\n", " lincombs.append(summ)\n", " else:\n", " lincombs.append(1e10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the linear combinations $\\sum_{i} m_i \\lambda_i $ we select the one that is closest to every eigenvalue, that is we take \n", "\n", "$$\n", "D(\\lambda_j) = \\text{min}_m |\\lambda_j - \\sum_{i} m_i \\lambda_i |\n", "$$" ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [], "source": [ "mindist = []\n", "minlincomb = []\n", "for i in range(len(eigenvalues)):\n", " distances = []\n", " for j in range(len(lincombs)):\n", " distances.append(np.abs(eigenvalues[i] - lincombs[j]))\n", " amax = np.argmin(distances)\n", " mindist.append(distances[amax])\n", " minlincomb.append(poww[amax,:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We then compute a relative metric of resonance-nearness,\n", "$$\n", "\\frac{D(\\lambda_j)}{|\\lambda_j|}\n", "$$" ] }, { "cell_type": "code", "execution_count": 146, "metadata": {}, "outputs": [], "source": [ "relative_dist = mindist/np.abs(eigenvalues)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The eigenvalue closest to resonance is\n", "\n" ] }, { "cell_type": "code", "execution_count": 147, "metadata": {}, "outputs": [], "source": [ "closest_index = np.argmin(relative_dist)" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "20" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "closest_index" ] }, { "cell_type": "code", "execution_count": 315, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.0024162315256366787" ] }, "execution_count": 315, "metadata": {}, "output_type": "execute_result" } ], "source": [ "relative_dist[closest_index]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The closest near-resonance observed is at \n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "from sympy import latex\n", "from IPython.display import display_latex\n", "\n", "\n", "\n", "def disp(idx, symObj):\n", " eqn = '$' + idx + ' ' + latex(symObj) + '$'\n", " display_latex(eqn,raw=True)\n", " return" ] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\[\\lambda_{20}= \\mathtt{\\text{(-0.065289236+0.0082860247j)}}\\]" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disp('\\lambda_{20}=', eigenvalues[closest_index])\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and the closest linear combination is\n", "\n" ] }, { "cell_type": "code", "execution_count": 171, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "\\[\\lambda_{1} + \\lambda_{4} + 3 \\lambda_{8}= \\mathtt{\\text{(-0.065141413+0.0082274116j)}}\\]" ] }, "execution_count": 171, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disp('\\lambda_{1} + \\lambda_{4} + 3 \\lambda_{8}=', eigenvalues[0] + eigenvalues[3] + 3*eigenvalues[7])" ] }, { "cell_type": "code", "execution_count": 158, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.01976398-0.j , -0.01511716+0.00822741j,\n", " -0.02326274-0.j ])" ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eigenvalues[(minlincomb[closest_index])>0]" ] }, { "cell_type": "code", "execution_count": 316, "metadata": {}, "outputs": [ { "data": { "image/png": "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ff/735ck7dixQ08++aQKhUJ9YcBjx47pZz/7md58801J0iOPPKJt27Zpbm5OkvT5z39ew8PDev755yVJd911lx5//HG98MIL+u1vfytJeuKJJ1Qul/Xzn/9ckrR//37dunVLb7zxhiTpoYce0sMPP6zz589LkgYGBpROp/Xcc8/pww8/lCR94xvf0A9/+EMtLFQrKA4dOqT3339fP/rRjyRJX/jCF/Tggw/WF+S79957dfjwYT377LP1MQRPP/20Ll26pLfffluS9Oijj+rGjRv68Y9/LEnas2eP7rvvPv3gBz+QJH3mM5/RY489pnPnzsndZWY6fvy4XnnlFf3617+WJH3ta1/TO++8U6/Z77XnafDDt5t/Q/DBr3SxUFjzefrXf/1X/e53v5NUHcfxyiuvaMeOHV17nn7xi1/oz//8z3XmzBmdPHlSd95557LtDz74oP73s5XP03PPPae33367b/6eDn3wK1mTi8Q/fFvv/sd/tPT3tJlaTTw6SVQAAPFn7u11iAQzfp1QtUflvKqr24+o2nPxD8HPBVWnL55x93/pKNDq9JZjjQMvzew9SXua1B6v2lbVMrANnadmaGjIr1692kn4QGdeeiAo71lhx2elw/+26s1qY1TMTH/zN3+jf/qnf5K766WXXupab0et1KvWs3LixAmdPXu2vh1Wz0oul1u2EGLPa/MaacbMrrn7UFfiAu8hAPpKt99D2h5g7+4Xg2kZh939e8Hq9jl3P+HuN1XtWj8oqdBpohJoZeaWtdoyAwxi5807ntCHS8v3fbhU3b+WF154QWamF198UadPn9aLL74oM9MLL7zQlbhqiUo+n9fp06d14sQJfetb39KJEyd0+vTpeolY4yD8rfLoo49u+X2Gqd1rBJvHzL5qZrmbN9ceWwYgHLlcTocOHar3/iOaOlrBvolBM/sLM/t6sLL9t919rhsnXm/mlmDtlMR6bZkBBnH06ps79dau71S/JZdJOz6rt3Z9R6++uXPN2+3evVsvvvhivWejNoZl9+7uVGaWy+VlPSe3bt3S9773Pd26dat+f/l8XuVyuSv314obN25s+X2Gqd1rBJvH3V9299GdO/vjObhy5YrOnj2rK1euhB0KsK5cLqexsTFdunRJY2NjJCwR1nYZWP0EZnc1bA6oOlD9mLuf6OjEze9rUFJa1d6RpLtnG45dkDTr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", "text/plain": [ "
" ] }, "execution_count": 316, "metadata": { "needs_background": "light" }, "output_type": "execute_result" } ], "source": [ "f = plt.figure()\n", "import matplotlib\n", "ratio = 8/5\n", "ax = f.add_subplot(122)\n", "ax2 = f.add_subplot(121)\n", "\n", "f.set_size_inches(3.38*2*1.7, (3.38*2)/ratio, forward=True)\n", "ax.loglog(np.abs(eigenvalues), mindist/np.abs(eigenvalues), '.', c='black')\n", "ax.text(.96*np.abs(eigenvalues)[20], 1.05*(mindist/np.abs(eigenvalues))[20], '$\\\\lambda_{20}$', fontsize = 17)\n", "ax.loglog(np.abs(eigenvalues)[20], (mindist/np.abs(eigenvalues))[20], 'o', c='crimson')\n", "\n", "ax.set_xlabel(r'$|\\lambda|$', fontsize = 25)\n", "ax.set_ylabel(r'$\\frac{D(\\lambda)}{|\\lambda|}$', rotation=0, labelpad = 20, fontsize = 20)\n", "ax2.plot([-0.075, 0.025], [0,0], '--', c='black', alpha = 0.5, linewidth =0.8)\n", "ax2.plot([0, 0.0], [-0.035,0.035], '--', c='black', alpha = 0.5, linewidth =0.8)\n", "\n", "ax2.plot(np.real(eigenvalues), np.imag(eigenvalues), 'x', c='black')\n", "ax2.plot(np.real(eigenvalues)[20], np.imag(eigenvalues)[20], 'o', c='crimson')\n", "ax2.text(1.05*np.real(eigenvalues)[20], 1.18*np.imag(eigenvalues)[20], '$\\\\lambda_{20}$', fontsize = 17)\n", "\n", "ax2.plot(np.real(eigenvalues)[0], np.imag(eigenvalues)[0], 'o', c='orange')\n", "ax2.text(.95*np.real(eigenvalues)[0], 0.0015 + np.imag(eigenvalues)[0], '$\\\\lambda_{1}$', fontsize = 17)\n", "\n", "ax2.plot(np.real(eigenvalues)[3], np.imag(eigenvalues)[3], 'o', c='orange')\n", "ax2.text(1.05*np.real(eigenvalues)[3], 1.18*np.imag(eigenvalues)[3], '$\\\\lambda_{4}$', fontsize = 17)\n", "\n", "\n", "ax2.plot(np.real(eigenvalues)[7], np.imag(eigenvalues)[7], 'o', c='orange')\n", "ax2.text(1.15*np.real(eigenvalues)[7], 0.0019+np.imag(eigenvalues)[7], '$3\\\\lambda_{8}$', fontsize = 17)\n", "\n", "\n", "ax2.set_xlim(-0.075, 0.025)\n", "ax2.set_ylim(-0.035, 0.035)\n", "\n", "ax2.set_xlabel(r'real$(\\lambda)$', fontsize = 20)\n", "ax2.set_ylabel(r'imag$(\\lambda)$', fontsize = 20)\n", "\n", "from matplotlib import ticker\n", "\n", "ax.set_xlim(0.006, 0.1)\n", "#ax.set_ylim(0.005, 0.06)\n", "f.tight_layout()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculating the spectrum of the laminar flow" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import sympy as sy" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from sympy.vector import CoordSys3D, Del\n", "from sympy.vector import divergence, gradient, curl, matrix_to_vector, dot, cross\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "r, phi, z, t = sy.symbols('r \\\\varphi z t')\n", "ur = sy.Function('u_r')(r, phi, z, t)\n", "uphi = sy.Function('u_\\\\varphi')(r, phi, z, t)\n", "uz = sy.Function('u_z')(r, phi, z, t)\n", "p = sy.Function('p')(r, phi, z, t)\n", "nu = sy.symbols('\\\\nu')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "R = CoordSys3D('R', transformation='cylindrical', variable_names=(\"r\", \"phi\", \"z\"))\n", "to_cyl_sub = {r:R.r, phi:R.phi, z:R.z}\n", "from_cyl_sub = {R.r:r, R.phi:phi, R.z:z}" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "u = ur.subs(to_cyl_sub)*R.i + uphi.subs(to_cyl_sub)*R.j + uz.subs(to_cyl_sub)*R.k" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "umatrix = u.to_matrix(R).subs(from_cyl_sub)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "laplacian = sy.simplify(curl(curl(u)) - gradient(divergence(u))).to_matrix(R).subs(from_cyl_sub)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "ugradu = sy.simplify((gradient(dot(u,u)) - 2* cross(u, curl(u)))/2).to_matrix(R)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "gradp = gradient(p.subs(to_cyl_sub)).to_matrix(R).subs(from_cyl_sub)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "nonlinearity = ugradu.subs(from_cyl_sub)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "navierstokes = umatrix.diff(t) + ugradu.subs(from_cyl_sub) + gradp - nu * laplacian" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "from sympy import latex\n", "from IPython.display import display_latex\n", "\n", "\n", "\n", "def disp(idx, symObj):\n", " eqn = '\\\\[' + idx + ' ' + latex(symObj) + '\\\\]'\n", " display_latex(eqn,raw=True)\n", " return" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\mathcal{N}(\\mathbf{u})= \\left[\\begin{matrix}- \\frac{\\nu \\left(- r^{2} \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} - r^{2} \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} - r \\frac{\\partial}{\\partial r} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + 2 \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}\\right)}{r^{2}} + \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial r} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial z} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial r} p{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\operatorname{u_{\\varphi}}^{2}{\\left(r,\\varphi,z,t \\right)}}{r} + \\frac{\\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}}{r}\\\\- \\frac{\\nu \\left(- r^{2} \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - r^{2} \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - r \\frac{\\partial}{\\partial r} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - 2 \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}\\right)}{r^{2}} + \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial r} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial z} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}}{r} + \\frac{\\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)}}{r} + \\frac{\\frac{\\partial}{\\partial \\varphi} p{\\left(r,\\varphi,z,t \\right)}}{r}\\\\- \\nu \\left(- \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\frac{\\partial}{\\partial r} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}}{r} - \\frac{\\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}}{r^{2}}\\right) + \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial r} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial z} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial z} p{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}}{r}\\end{matrix}\\right]$" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disp('\\\\mathcal{N}(\\mathbf{u})=',navierstokes)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "uhp = sy.Matrix([0,0,1-r**2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## We now linearize around the parabolic profile\n", "$$\n", "\\mathbf{u}_{HP} = \\begin{pmatrix}0 \\\\ 0 \\\\ 1-r^2 \\end{pmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "epsilon = sy.symbols('\\\\varepsilon')\n" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "Linearized_Ns = navierstokes.subs([(ur, epsilon*ur),\n", " (uphi, epsilon*uphi),\n", " (uz, 1-r**2 + epsilon * uz),\n", " (p, 4*nu*z + epsilon*p)])\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "Linearized_Ns = Linearized_Ns.diff(epsilon).subs(epsilon, 0).doit()" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$D\\mathcal{N}(\\mathbf{u}_{HP})= \\left[\\begin{matrix}- \\frac{\\nu \\left(- r^{2} \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} - r^{2} \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} - r \\frac{\\partial}{\\partial r} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + 2 \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}\\right)}{r^{2}} + \\left(1 - r^{2}\\right) \\frac{\\partial}{\\partial z} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial r} p{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}\\\\- \\frac{\\nu \\left(- r^{2} \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - r^{2} \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - r \\frac{\\partial}{\\partial r} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} - 2 \\frac{\\partial}{\\partial \\varphi} \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)}\\right)}{r^{2}} + \\left(1 - r^{2}\\right) \\frac{\\partial}{\\partial z} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{\\varphi}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\frac{\\partial}{\\partial \\varphi} p{\\left(r,\\varphi,z,t \\right)}}{r}\\\\- \\nu \\left(- \\frac{\\partial^{2}}{\\partial r^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\partial^{2}}{\\partial z^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} - \\frac{\\frac{\\partial}{\\partial r} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}}{r} - \\frac{\\frac{\\partial^{2}}{\\partial \\varphi^{2}} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}}{r^{2}}\\right) - 2 r \\operatorname{u_{r}}{\\left(r,\\varphi,z,t \\right)} + \\left(1 - r^{2}\\right) \\frac{\\partial}{\\partial z} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial z} p{\\left(r,\\varphi,z,t \\right)} + \\frac{\\partial}{\\partial t} \\operatorname{u_{z}}{\\left(r,\\varphi,z,t \\right)}\\end{matrix}\\right]$" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disp('D\\mathcal{N}(\\mathbf{u}_{HP})=',Linearized_Ns)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "k, m= sy.symbols('k m', integers=True)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "alpha = sy.symbols('\\\\alpha')\n", "lamb = sy.symbols('\\\\lambda')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "ii = sy.sqrt(-1)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "ar = sy.Function('a_r')(r)\n", "aphi = sy.Function('a_\\\\varphi')(r)\n", "az = sy.Function('a_z')(r)\n", "ap = sy.Function('a_p')(r)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This operator can be decomposed to normal modes of the form \n", "\n", "$$\n", "\\mathbf{u} = ae^{ik\\alpha z} e^{ikm\\varphi} e^{\\lambda t}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We expect that the least stable mode is obtained with $m=0$, in which case the equation simplifies to the eigenvalue equation" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "Normalmode_ns = Linearized_Ns.subs([(ur, ar*sy.exp(ii*m*phi + ii*k*alpha*z)*sy.exp(lamb*t)),\n", " (uphi,aphi*sy.exp(ii*m*phi + ii*k*alpha*z)*sy.exp(lamb*t)),\n", " (uz,az*sy.exp(ii*m*phi + ii*k*alpha*z)*sy.exp(lamb*t)),\n", " (p, ap*sy.exp(ii*m*phi + ii*k*alpha*z)*sy.exp(lamb*t))]).doit()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "Normalmode_ns = sy.simplify(Normalmode_ns/(sy.exp(ii*m*phi + ii*k*alpha*z)*sy.exp(lamb*t)))" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "equation = sy.Matrix([eq for eq in Normalmode_ns])" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "simplified_eq = equation.subs(k, 0).subs(ar,0).subs(aphi, 0).subs(ap,0).doit()" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$0= \\lambda \\operatorname{a_{z}}{\\left(r \\right)} - \\frac{\\nu m^{2} \\operatorname{a_{z}}{\\left(r \\right)}}{r^{2}} + \\nu \\frac{d^{2}}{d r^{2}} \\operatorname{a_{z}}{\\left(r \\right)} + \\frac{\\nu \\frac{d}{d r} \\operatorname{a_{z}}{\\left(r \\right)}}{r}$" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disp('0=',simplified_eq[2])\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (system-wide)", "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.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }