In [1]:
%matplotlib notebook
from sympy import init_printing
from sympy import S
from sympy import sin, cos, tanh, exp, pi, sqrt
from boutdata.mms import Delp2, DDX, DDY, DDZ
from boutdata.mms import x, y, z, t
import os, sys
# If we add to sys.path, then it must be an absolute path
common_dir = os.path.abspath('./../../../../common')
# Sys path is a list of system paths
sys.path.append(common_dir)
from CELMAPy.MES import get_metric, make_plot, BOUT_print
init_printing()
In [2]:
folder = '../twoGaussians/'
metric = get_metric()
In [3]:
# Initialization
the_vars = {}
We have that
$$\Omega^D = \nabla\cdot(n\nabla_\perp\phi) = n\nabla_\perp^2\phi + \nabla n\cdot \nabla_\perp \phi = n\nabla_\perp^2\phi + \nabla_\perp n\cdot \nabla_\perp \phi$$Due to orthogonality we have that $$\nabla_\perp n\cdot \nabla_\perp \phi = \mathbf{e}^i\cdot \mathbf{e}^i(\partial_i n)(\partial_i \phi) = g^{xx}(\partial_x n)(\partial_x \phi) + g^{zz}(\partial_z n)(\partial_z \phi) = (\partial_x n)(\partial_x \phi) + \frac{1}{x^2}(\partial_z n)(\partial_z \phi)$$
We will use the Delp2
operator for the perpendicular Laplace operator (as the y-derivatives vanishes). We have
Delp2
$(f)=g^{xx}\partial_x^2 f + g^{zz}\partial_z^2 f + 2g^{xz}\partial_x\partial_z f + G^1\partial_x f + G^3\partial_z f$
Using the cylinder geometry, we get that
Delp2
$(f)=\partial_x^2 f + \frac{1}{x^2}\partial_z^2 f + \frac{1}{x}\partial_x f$
This gives
$$\Omega^D = \nabla\cdot(n\nabla_\perp\phi) = n\partial_x^2 \phi + n\frac{1}{x^2}\partial_z^2 \phi + n\frac{1}{x}\partial_x \phi + (\partial_x n)(\partial_x \phi) + \frac{1}{x^2}(\partial_z n)(\partial_z \phi)$$NOTE:
In [4]:
# We need Lx
from boututils.options import BOUTOptions
myOpts = BOUTOptions(folder)
Lx = eval(myOpts.geom['Lx'])
In [5]:
# Two gaussians
# The skew sinus
# In cartesian coordinates we would like a sinus with with a wave-vector in the direction
# 45 degrees with respect to the first quadrant. This can be achieved with a wave vector
# k = [1/sqrt(2), 1/sqrt(2)]
# sin((1/sqrt(2))*(x + y))
# We would like 2 nodes, so we may write
# sin((1/sqrt(2))*(x + y)*(2*pi/(2*Lx)))
# Rewriting this to cylindrical coordinates, gives
# sin((1/sqrt(2))*(x*(cos(z)+sin(z)))*(2*pi/(2*Lx)))
# The gaussian
# In cartesian coordinates we would like
# f = exp(-(1/(2*w^2))*((x-x0)^2 + (y-y0)^2))
# In cylindrical coordinates, this translates to
# f = exp(-(1/(2*w^2))*(x^2 + y^2 + x0^2 + y0^2 - 2*(x*x0+y*y0) ))
# = exp(-(1/(2*w^2))*(rho^2 + rho0^2 - 2*rho*rho0*(cos(theta)*cos(theta0)+sin(theta)*sin(theta0)) ))
# = exp(-(1/(2*w^2))*(rho^2 + rho0^2 - 2*rho*rho0*(cos(theta - theta0)) ))
# A parabola
# In cartesian coordinates, we have
# ((x-x0)/Lx)^2
# Chosing this function to have a zero value at the edge yields in cylindrical coordinates
# ((x*cos(z)+Lx)/(2*Lx))^2
# +2 to ensure positivity of n
w = 0.8*Lx
rho0 = 0.3*Lx
theta0 = 5*pi/4
the_vars['n'] = sin((1/sqrt(2))*(x*(cos(z)+sin(z)))*(2*pi/(2*Lx)))*\
exp(-(1/(2*w**2))*(x**2 + rho0**2 - 2*x*rho0*(cos(z - theta0)) ))*\
((x*cos(z)+Lx)/(2*Lx))**2\
+2
# The gaussian
# In cartesian coordinates we would like
# f = exp(-(1/(2*w^2))*((x-x0)^2 + (y-y0)^2))
# In cylindrical coordinates, this translates to
# f = exp(-(1/(2*w^2))*(x^2 + y^2 + x0^2 + y0^2 - 2*(x*x0+y*y0) ))
# = exp(-(1/(2*w^2))*(rho^2 + rho0^2 - 2*rho*rho0*(cos(theta)*cos(theta0)+sin(theta)*sin(theta0)) ))
# = exp(-(1/(2*w^2))*(rho^2 + rho0^2 - 2*rho*rho0*(cos(theta - theta0)) ))
# Multiplication of cos(pi*x/(2*Lx)) to give zero boundaries
w = 0.5*Lx
rho0 = 0.2*Lx
theta0 = pi
the_vars[r'$\phi$'] = exp(-(1/(2*w**2))*(x**2 + rho0**2 - 2*x*rho0*(cos(z - theta0)) ))*cos(pi*x/(2*Lx))
We have that
$$\Omega^D = \nabla\cdot(n\nabla_\perp(\phi))$$
In [6]:
# Calculate the solution
the_vars['vortD'] = the_vars['n']*Delp2(the_vars[r'$\phi$'], metric=metric)\
+ metric.g11*DDX(the_vars['n'], metric=metric)*DDX(the_vars[r'$\phi$'], metric=metric)\
+ metric.g33*DDZ(the_vars['n'], metric=metric)*DDZ(the_vars[r'$\phi$'], metric=metric)
In [7]:
make_plot(folder=folder, the_vars=the_vars, plot2d=True, include_aux=False, save = True)
In [8]:
BOUT_print(the_vars, rational=False)