Python 中的广义相对论
我曾在Linux Journal中介绍过几种不同的用于科学计算的软件包,但我没有花太多时间描述可用的库以及可以使用这些库完成的工作类型。因此,在本文中,我将介绍 SymPy,这是一个 Python 模块,允许您进行符号数学运算,特别是介绍一个名为 GraviPy 的实用程序,它建立在 SymPy 之上。使用此实用程序,您可以进行各种您在研究广义相对论时想要进行的计算。
您可以使用 pip 和以下命令安装这两个模块
sudo pip install sympy
sudo pip install gravipy
然后,您可以使用以下 Python 语句从这两个模块导入所有内容
from sympy import *
from gravipy import *
这样,您就可以在您自己的 Python 代码的命名空间中访问这些模块的所有功能。
当您进行广义相对论研究时,您经常需要查看非常复杂的方程式。GraviPy 模块包含一个名为 init_printing()
的函数,该函数设置了漂亮打印方程式所需的一切。您可能需要在代码顶部附近调用它,以便您的工作表更易于阅读。
让我们从 SymPy Python 模块开始。SymPy 旨在让您能够进行符号数学计算。使用它,您可以执行诸如求解代数表达式、重新排列和简化方程式,甚至执行符号导数和积分之类的操作。我在LJ的上一期中介绍过 SymPy,所以在这里,我只关注一些核心部分作为提醒。
第一个必要的步骤是定义您将在计算中使用的符号变量。使用 symbols
命令,您可以使用以下方法定义它们
x,y,z = symbols('x y z')
这样,您就可以定义在笛卡尔坐标系中定义三个空间维度的变量。
如果您想在球坐标系中定义所有四个时空坐标,您可以使用这个
t, r, theta, phi = symbols('t, r, \\theta, \phi')
请记住,您正在将字符串输入到 symbols 函数中。这意味着您需要转义任何特殊字符以获得您期望的结果。
这些命令将为您提供可以在表达式中使用的符号变量。但是,广义相对论有一类特殊的变量,称为坐标,用于定义时空本身。有一个名为 Coordinates
的类,可以帮助定义这一点。使用上面的球坐标,您可以使用以下语句创建坐标
x = Coordinates('\chi', [t, r, theta, phi])
四个时空坐标存储在对象 x
中。您可以使用索引访问各个坐标。在广义相对论中,有两种不同的变量索引方式:协变索引和逆变索引。要查看协变版本的元素值,您需要使用正索引值。负索引值将为您提供逆变版本。例如,如果您想获取时间变量,您将使用以下方法
x(-1)
您应该立即注意到,这暗示 GraviPy 使用基于 1 的索引而不是基于 0 的索引。
现在您有了一组变量来定义要使用的时空坐标,让我们继续讨论实际的广义相对论。
广义相对论的核心部分是度规。度规定义了时空的形状。这种时空形状定义了引力。解释正在发生的事情的常用短语是,物质告诉时空如何弯曲,时空告诉物质如何移动。要在 GraviPy 中定义度规,您需要首先创建一个度规张量对象。您可以使用以下语句执行此操作
Metric = diag(-(1-2*M/r), 1/(1-2*M/r), r**2, r**2*sin(theta)**2)
在本例中,您会注意到一个名为 M
的新变量,它表示正在创建这种时空扭曲的物质的质量。如果它是一个将保持静态的项目,则您无需执行任何额外的操作。但是,没有理由让它保持静态。如果它是可以更改的东西,您需要使用 symbols
命令来定义它。在其最一般的形式中,度规张量是一个 4x4 的元素矩阵。上面的示例是一个对角度规,其中只有非零元素沿对角线。一旦您有了这个张量对象,您就可以使用以下语句基于它定义度规
g = MetricTensor('g', x, Metric)
此示例为函数提供了度规定义和要使用的坐标系。
要访问各个元素,您可以使用遵循与上述相同格式的索引。例如,您可以使用以下方法
g(1, 1) -> 2M/r-1
对于向量和张量,您可以使用一个名为 All
的特殊索引,它将为您提供所讨论索引的每个可能值。例如,您可以使用以下方法获取整个坐标列表
x(-All) -> [t r theta phi]
您可以使用以下语句获取度规张量的所有元素
g(All, All)
现在您有了一组坐标和一个度规张量,需要计算许多标准张量,以帮助确定时空的几何形状实际上是什么样子,以及诸如光束之类的东西如何通过这种几何形状传播。GraviPy 模块包括张量类 Christoffel
、Riemann
、Ricci
、Einstein
和 Geodesic
。Christoffel
、Riemann
和 Ricci
张量仅取决于度规。因此,它们都具有非常相似的形式来创建新实例并从中获取结果。例如,您可以使用以下语句定义 Christoffel
张量值
Ga = Christoffel('Ga', g)
您可以像使用度规张量一样,使用索引获取各个元素。但是,其中一些张量可能有很多不重要的零条目。因此,您可以使用以下语句获取非零值
Ga.components
这将返回一个字典,其中键是此特定值所在位置的坐标集,以及该点的实际非零值。
Einstein
张量是用于时空实际爱因斯坦方程的张量,它们略有不同。为了计算它们,您首先需要使用以下语句计算 Ricci
张量
Ri = Ricci('Ri', g)
一旦您有了这个张量,您可以使用以下方法计算 Einstein
张量
G = Einstein('G', Ri)
在结束之前,我应该看看两种对于进行广义相对论研究绝对必要的技术。第一个是指标收缩。这是您最终对张量中两个指标的值求和的地方。在 Python 中,您可以通过显式求和来做到这一点
Rm = Riemann('Rm', g)
ricci = sum([Rm(i, All, k, All)*g(-i, -k) for i, k in
↪list(variations(range(1, 5), 2, True))], zeros(4))
这两行等效于上面单个 Ricci
张量的创建。在许多情况下,复杂的计算不会自动简化。这意味着您需要使用以下命令显式地进行此简化
ricci.simplify()
另一项重要技术是计算测地线,测地线是定义光束如何在此时空中传播的方程。您需要创建一个新变量来处理这些方程的世界线参数
tau = symbols('\\tau')
现在,您可以使用以下方法计算测地线
w = Geodesic('w', g, tau)
同样,您可以使用基于 1 的索引来访问您感兴趣的时空的各种非平凡方程。
借助 SymPy,您可以进行各种通常为 Maple、Maxima 或 Mathematica 等程序保留的符号计算。基于这些功能,GraviPy 让您可以玩转时空,并进行计算以确定曲率和引力效应。在线上没有大量信息解释 GraviPy 可以做什么。即使您通过 pip 安装 GraviPy,您最好的选择是下载源文件,其中包括一个教程 iPython 笔记本。现在,您可以完全在舒适的 Python 环境中进行引力研究。如果您是 Python 爱好者,此模块将让您使用您喜欢的语言进行有趣的研究工作。