Advertisement
Guest User

Find metric library

a guest
Oct 31st, 2015
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.41 KB | None | 0 0
  1. import sympy as sym
  2.  
  3. def curve_to_metric(ds2,dim):
  4.     if dim < 2:
  5.         raise ValueError("The metric is implemented for at least dim = 2.")
  6.     ds2 = str(ds2)
  7.     ds2 = ds2.replace(' ','')
  8.     differentials = []
  9.     if dim >= 2:
  10.         differentials = ['du','dv']
  11.     if dim >= 3:
  12.         differentials.append('dw')
  13.     if dim == 4:
  14.         differentials.append('dt')
  15.     for diff in differentials:
  16.         ds2 = ds2.replace(diff+'**2',diff+'*'+diff)
  17.    
  18.     def split_elements(expr,tmp_list,side='right'):
  19.         new_list = []
  20.         if type(tmp_list) is list:
  21.             for term in tmp_list:
  22.                 split_terms = term.split(expr)
  23.                 if type(split_terms) is list:
  24.                     for sterms in split_terms:
  25.                         new_list.append(sterms)
  26.                 else:
  27.                     new_list.append(split_terms)
  28.         else:
  29.             split_terms = tmp_list.split(expr) # split at found expression
  30.             if type(split_terms) is list:
  31.                 for sterms in split_terms:
  32.                     new_list.append(sterms)
  33.             else:
  34.                 new_list.append(split_terms)
  35.        
  36.         lost = expr[:-1]
  37.         sign = '-' # special case to be handeled
  38.         if side=='left':
  39.             lost = expr[1:]
  40.         for i in range(len(new_list)):
  41.             term = new_list[i]
  42.             if side=='left':
  43.                 first = 0
  44.                 if term[first] == '*':
  45.                     new_list[i] = lost+new_list[i]
  46.             else:
  47.                 last = len(term) - 1
  48.                 if term[last] == '*':
  49.                     new_list[i] = new_list[i]+lost
  50.                     if expr[-1] == sign: # if expression contains '-' at end
  51.                         # for next in list add '-'
  52.                         new_list[i+1] = '-'+new_list[i+1]
  53.         return new_list
  54.  
  55.     n = ds2
  56.     L='left'
  57.     R='right'
  58.     p = '+'
  59.     m = '-'
  60.     for diff in differentials: # for each differential : dx_i = du,dv,dw,dt
  61.         expr = diff+p # 'dx_i+'
  62.         n = split_elements(expr,n,R)
  63.         expr = diff+m # 'dx_i-'
  64.         n = split_elements(expr,n,R)
  65.         expr = p+diff # '+dx_i'
  66.         n = split_elements(expr,n,L)
  67.         expr = m+diff # '-dx_i'
  68.         n = split_elements(expr,n,L)
  69.    
  70.     # define the matrix structure of the metric components for mapping the
  71.     if dim == 2: # curve elements to their corresponding location
  72.         diff  = [['du*du','du*dv'],
  73.                  ['dv*du','dv*dv']]
  74.     if dim == 3:
  75.         diff  = [['du*du','du*dv','du*dw'],
  76.                  ['dv*du','dv*dv','dv*dw'],
  77.                  ['dw*du','dw*dv','dw*dw']]
  78.     if dim == 4:
  79.         diff  = [['du*du','du*dv','du*dw','dt*du'],
  80.                  ['dv*du','dv*dv','dv*dw','dv*dt'],
  81.                  ['dw*du','dv*dw','dw*dw','dw*dt'],
  82.                  ['dt*du','dt*dv','dt*dw','dt*dt']]
  83.     # add the elements in g without the above differentials
  84.     elements = n
  85.     g =  [['0' for _ in range(dim)] for _ in range(dim)]
  86.     for element in elements:
  87.         for i in range(dim):
  88.             for j in range(dim):
  89.                 if (element.find(diff[i][j]) != -1):
  90.                     if (element.find('*' + diff[i][j]) != -1):
  91.                         g[i][j] = element.replace('*'+ diff[i][j],'')
  92.                     else:
  93.                         g[i][j] = element.replace(diff[i][j],'1')
  94.                     g[j][i] = g[i][j]
  95.     from sympy import Matrix, sin, cos, exp, log, cosh, sinh, sqrt, tan, tanh
  96.     from sympy.abc import u,v,w,t
  97.     return Matrix(g)
  98.  
  99.  
  100. def metric(coord1,coord2,form="simplified",write_to_file=False):
  101.     """
  102.    Calculates the metric for the coordinate transformation
  103.    between cartesian coordinates to another orthogonal
  104.    coordinate system.
  105.    """
  106.     from sympy import diff
  107.     x,y = coord1[0], coord1[1]
  108.     u,v = coord2[0], coord2[1]
  109.     dim = len(coord1)
  110.     if len(coord2) != dim:
  111.         import sys
  112.         sys.exit("Coordinate systems must have same dimensions.")
  113.     if dim >= 3:
  114.         z = coord1[2]
  115.         w = coord2[2]
  116.     if dim == 4:
  117.         t1 = coord1[3]
  118.         t2 = coord2[3]
  119.     dxdu = diff(x,u)
  120.     dxdv = diff(x,v)
  121.     dydu = diff(y,u)
  122.     dydv = diff(y,v)
  123.     if dim >= 3:
  124.         dxdw = diff(x,w)
  125.         dydw = diff(y,w)
  126.         dzdu = diff(z,u)
  127.         dzdv = diff(z,v)
  128.         dzdw = diff(z,w)
  129.     if dim == 4:
  130.         dxdt = diff(x,t2)
  131.         dydt = diff(y,t2)
  132.         dzdt = diff(z,t2)
  133.         dtdu = diff(t1,u)
  134.         dtdv = diff(t1,v)
  135.         dtdw = diff(t1,w)
  136.         dtdt = diff(t1,t2)
  137.        
  138.  
  139.     import numpy as np
  140.     from sympy import Matrix
  141.     g = Matrix(np.zeros([dim,dim]))
  142.     g[0,0] = dxdu*dxdu + dydu*dydu
  143.     g[0,1] = dxdu*dxdv + dydu*dydv
  144.     g[1,1] = dxdv*dxdv + dydv*dydv
  145.     g[1,0] = g[0,1]
  146.     if dim >= 3:
  147.         g[0,0] += dzdu*dzdu
  148.         g[0,1] += dzdu*dzdv; g[1,0] = g[0,1]
  149.         g[0,2] = dxdu*dxdw + dydu*dydw + dzdu*dzdw; g[2,0] = g[0,2]
  150.         g[1,1] += dzdv*dzdv
  151.         g[1,2] = dxdv*dxdw + dydv*dydw + dzdv*dzdw; g[2,1] = g[1,2]
  152.         g[2,2] = dxdw*dxdw + dydw*dydw + dzdw*dzdw
  153.     if dim == 4:
  154.         g[0,0] += dtdu*dtdu
  155.         g[0,1] += dtdu*dtdv; g[1,0] = g[0,1]
  156.         g[0,2] += dtdu*dtdw; g[2,0] = g[0,2]
  157.         g[0,3] = dxdu*dxdt + dydu*dydt + dzdu*dzdt + dtdu*dtdt; g[3,0] = g[0,3]
  158.         g[1,1] += dtdv*dtdv
  159.         g[1,2] += dtdv*dtdw; g[2,1] = g[1,2]
  160.         g[1,3] = dxdv*dxdt + dydv*dydt + dzdv*dzdt + dtdv*dtdt; g[3,1] = g[1,3]
  161.         g[2,2] += dtdw*dtdw
  162.         g[2,3] = dxdw*dxdt + dydw*dydt + dzdw*dzdt + dtdw*dtdt; g[3,2] = g[2,3]
  163.         g[3,3] = dxdt*dtdt + dydt*dtdt + dzdt*dtdt + dtdt*dtdt
  164.    
  165.     if form=="simplified":
  166.         def symplify_expr(expr):
  167.             new_expr = sym.trigsimp(expr)
  168.             new_expr = sym.simplify(new_expr)
  169.             return new_expr    
  170.         print "Performing simplification on the metric. This may take some time ...."
  171.         for i in range(0,dim):
  172.             for j in range(0,dim):
  173.                 g[i,j] = symplify_expr(g[i,j])
  174.  
  175.     if write_to_file:
  176.         f = open("metric.txt","w")
  177.         f.write(str(g))
  178.         f.close()
  179.     return g
  180.  
  181. def toroidal_coordinates(form="simplified"):
  182.     from sympy.abc import u, v, w, a
  183.     from sympy import sin,cos,sinh,cosh
  184.  
  185.     x = (a*sinh(u)*cos(w))/(cosh(u) - cos(v))
  186.     y = (a*sinh(u)*sin(w))/(cosh(u) - cos(v))  
  187.     z = (a*sin(v))/(cosh(u) - cos(v))
  188.     coord1 = (x,y,z)
  189.     coord2 = (u,v,w)
  190.     g = metric(coord1,coord2,form)
  191.     return g  
  192.  
  193. def cylindrical_coordinates(form="simplified"):
  194.     from sympy.abc import u, v, w, x, y, z
  195.     from sympy import sin,cos
  196.  
  197.     x = u*cos(v)
  198.     y = u*sin(v)
  199.     z = w
  200.     coord1 = (x,y,z)
  201.     coord2 = (u,v,w)
  202.     g = metric(coord1,coord2,form)
  203.     return g
  204.  
  205. def spherical_coordinates(form="simplified"):
  206.     """
  207.    from sympy.abc import u, v, w, x, y, z
  208.    from sympy import sin,cos
  209.  
  210.    x = u*sin(v)*cos(w)
  211.    y = u*sin(v)*sin(w)
  212.    z = u*cos(v)
  213.    coord1 = (x,y,z)
  214.    coord2 = (u,v,w)
  215.    """
  216.     from sympy.abc import r, theta, phi, x, y, z
  217.     from sympy import sin,cos
  218.  
  219.     x = r*sin(theta)*cos(phi)
  220.     y = r*sin(theta)*sin(phi)
  221.     z = r*cos(theta)
  222.     coord1 = (x,y,z)
  223.     coord2 = (r,theta,phi)
  224.     g = metric(coord1,coord2,form)
  225.     return g
  226.  
  227. def inverse_prolate_spheroidal_coordinates(form="usimp",write_to_file=True):
  228.     from sympy.abc import u, v, w, a
  229.     from sympy import sin,cos,sinh,cosh
  230.  
  231.     x = (a*sinh(u)*sin(v)*cos(w))/(cosh(u)**2 - sin(v)**2)
  232.     y = (a*sinh(u)*sin(v)*sin(w))/(cosh(u)**2 - sin(v)**2)  
  233.     z = (a*cosh(u)*cos(v))/(cosh(u)**2 - sin(v)**2)
  234.     coord1 = (x,y,z)
  235.     coord2 = (u,v,w)
  236.     g = metric(coord1,coord2,form,write_to_file)
  237.     return g
  238.  
  239. def cylindrical_catenoid_coordinates(form='simplified'):
  240.     from sympy.abc import u, v, w
  241.     from sympy import sin,cos
  242.     x = cos(u) - v*sin(u)
  243.     y = sin(u) + v*cos(u)
  244.     z = v
  245.     coord1 = (x,y,z)
  246.     coord2 = (u,v,w)
  247.     g = metric(coord1,coord2,form)
  248.     return g#[:2,:2] # 2-dimensional
  249.  
  250. def egg_carton_coordinates(form='simplified'):
  251.     from sympy.abc import u, v, w
  252.     from sympy import sin,cos
  253.     x = u
  254.     y = v
  255.     z = sin(u)*cos(v)
  256.     coord1 = (x,y,z)
  257.     coord2 = (u,v,w)
  258.     g = metric(coord1,coord2,form)
  259.     return g#[:2,:2] # 2-dimensional
  260.  
  261. def analytical(k_value=0,form="simplified"): # k=0 gives flat space
  262.     from sympy import sin
  263.     from sympy.abc import u,v,k
  264.    
  265.     ds2 = '(1/(1 - k*u**2))*du**2 + u**2*dv**2 + u**2*sin(v)**2*dw**2'
  266.  
  267.     g = curve_to_metric(ds2,3)
  268.     g = g.subs(k,k_value)  
  269.     return g
  270.  
  271. def kerr_metric(): #in polar coordinates u,v,w, and t
  272.     from sympy import symbols, simplify, cos, sin
  273.     from sympy.abc import G,M,l,u,v,w #,c,J
  274.     # from wikipedia :
  275.     """
  276.    ds2 = '(1 - us*u/p)*c**2*dt**2 - (p/l)*du**2 - p*dv**2 -\
  277.          (u**2 + a**2 + (us*u*a**2/p**2)*sin(v)**2)*sin(v)**2*dw**2\
  278.          + (2*us*u*a*sin(v)**2/p)*c*dt*dw'
  279.    g = curve_to_metric(ds2,dim=4)
  280.    
  281.    us,p,a,l = symbols('us,p,a,l')
  282.    g = g.subs({p:u**2 + a**2*cos(v)})
  283.    g = g.subs({l:u**2 - us*u + a**2})
  284.    g = g.subs({us:2*G*M/c**2})
  285.    g = g.subs({a:J/(M*c)})
  286.    """
  287.     # from Thomas A. Moore (if a=0 ds2 reduces to Schwarzchild solution)
  288.     ds2 = '-(1 - us*u/p)*dt**2 + (p/l)*du**2 + p*dv**2 \
  289.           + (u**2 + a**2 + (us*u*a**2*sin(v)**2/p**2))*sin(v)**2*dw**2\
  290.           - (2*us*u*a*sin(v)**2/p)*dt*dw'
  291.     g = curve_to_metric(ds2,dim=4)
  292.     us,p,a,l = symbols('us,p,a,l')
  293.     g = g.subs({p:u**2 + a**2*cos(v)})
  294.     g = g.subs({l:u**2 - us*u + a**2})
  295.     g = g.subs({us:2*G*M})
  296.    
  297.     print "Performing simplification on the metric. This may take some time ...."
  298.     g = simplify(g)
  299.     return g
  300.  
  301. def torus_metric(a=1,c=2,form='simplified'):
  302.     from sympy.abc import u, v, w
  303.     from sympy import sin,cos
  304.     x = (c + a*cos(u))*cos(v)
  305.     y = (c + a*cos(u))*sin(v)
  306.     z = sin(u)
  307.     coord1 = (x,y,z)
  308.     coord2 = (u,v,w)
  309.     g = metric(coord1,coord2,form)
  310.     return g#[:2,:2]
  311.  
  312. def egg_carton_metric(form='simplified'):
  313.     from sympy.abc import u, v, w
  314.     from sympy import sin,cos
  315.     x = u
  316.     y = v
  317.     z = sin(u)*cos(v)
  318.     coord1 = (x,y,z)
  319.     coord2 = (u,v,w)
  320.     g = metric(coord1,coord2,form)
  321.     return g#[:2,:2]
  322.  
  323. def flat_sphere():
  324.     """
  325.    from sympy.diffgeom import Manifold, Patch, CoordSystem, TensorProduct
  326.    from sympy import sin, trigsimp, simplify, Matrix
  327.    from sympy.diffgeom import metric_to_Riemann_components
  328.    dim = 2
  329.    m = Manifold("M",dim)
  330.    patch = Patch("P",m)
  331.    flat_sphere = CoordSystem("flat_sphere", patch, ["theta", "phi"])
  332.    theta,phi = flat_sphere.coord_functions()
  333.    from sympy.abc import r
  334.    g = Matrix([[r**2,0],[0,r**2*sin(theta)**2]])
  335.    diff_forms = flat_sphere.base_oneforms()
  336.    metric = sum([TensorProduct(di, dj)*g[i, j]
  337.               for i, di in enumerate(diff_forms)
  338.               for j, dj in enumerate(diff_forms)])
  339.    """
  340.     ds2 = 'u**2*dv**2 + u**2*sin(v)**2*dw**2'
  341.     g = curve_to_metric(ds2,dim=3)
  342.     return g#[1:,1:]
  343.  
  344. if __name__ == "__main__":
  345.     g1 = toroidal_coordinates()
  346.     print "Toroidal"
  347.     print g1
  348.  
  349.     """
  350.    g2 = cylindrical_coordinates()
  351.    print "\nCylindrical"
  352.    print g2
  353.  
  354.    g3 = spherical_coordinates()
  355.    print "\nSpherical"
  356.    print g3
  357.    
  358.    g4 = inverse_prolate_spheroidal_coordinates("usimp",1)
  359.    print "\nInverse prolate spheroidal coordinates - without simplified form"
  360.    print g4
  361.    """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement