PDE

用户功能

这些是使用 from sympy import * 导入到全局命名空间的函数。它们旨在供用户使用。

sympy.solvers.pde.pde_separate(eq, fun, sep, strategy='mul')[源代码][源代码]

在偏微分方程中,通过加法或乘法分离方法分离变量。它试图重写方程,使得指定的变量出现在方程的另一侧,而不是与其他变量在同一侧。

参数:
  • eq – 偏微分方程

  • fun – 原始函数 F(x, y, z)

  • sep – 分离函数列表 [X(x), u(y, z)]

  • strategy – 分离策略。你可以选择加法分离(’add’)和乘法分离(’mul’),后者是默认选项。

示例

>>> from sympy import E, Eq, Function, pde_separate, Derivative as D
>>> from sympy.abc import x, t
>>> u, X, T = map(Function, 'uXT')
>>> eq = Eq(D(u(x, t), x), E**(u(x, t))*D(u(x, t), t))
>>> pde_separate(eq, u(x, t), [X(x), T(t)], strategy='add')
[exp(-X(x))*Derivative(X(x), x), exp(T(t))*Derivative(T(t), t)]
>>> eq = Eq(D(u(x, t), x, 2), D(u(x, t), t, 2))
>>> pde_separate(eq, u(x, t), [X(x), T(t)], strategy='mul')
[Derivative(X(x), (x, 2))/X(x), Derivative(T(t), (t, 2))/T(t)]
sympy.solvers.pde.pde_separate_add(eq, fun, sep)[源代码][源代码]

用于搜索加性可分离解的辅助函数。

考虑一个包含两个自变量 x, y 和一个因变量 w 的方程,我们寻找两个依赖于不同参数的函数的乘积:

\(w(x, y, z) = X(x) + y(y, z)\)

示例

>>> from sympy import E, Eq, Function, pde_separate_add, Derivative as D
>>> from sympy.abc import x, t
>>> u, X, T = map(Function, 'uXT')
>>> eq = Eq(D(u(x, t), x), E**(u(x, t))*D(u(x, t), t))
>>> pde_separate_add(eq, u(x, t), [X(x), T(t)])
[exp(-X(x))*Derivative(X(x), x), exp(T(t))*Derivative(T(t), t)]
sympy.solvers.pde.pde_separate_mul(eq, fun, sep)[源代码][源代码]

用于搜索乘法可分离解的辅助函数。

考虑一个包含两个自变量 x, y 和一个因变量 w 的方程,我们寻找两个依赖于不同参数的函数的乘积:

\(w(x, y, z) = X(x)*u(y, z)\)

示例

>>> from sympy import Function, Eq, pde_separate_mul, Derivative as D
>>> from sympy.abc import x, y
>>> u, X, Y = map(Function, 'uXY')
>>> eq = Eq(D(u(x, y), x, 2), D(u(x, y), y, 2))
>>> pde_separate_mul(eq, u(x, y), [X(x), Y(y)])
[Derivative(X(x), (x, 2))/X(x), Derivative(Y(y), (y, 2))/Y(y)]
sympy.solvers.pde.pdsolve(
eq,
func=None,
hint='default',
dict=False,
solvefun=None,
**kwargs,
)[源代码][源代码]

解决任何(支持的)类型的偏微分方程。

用法

pdsolve(eq, f(x,y), hint) -> 使用方法提示 hint 求解函数 f(x,y) 的偏微分方程 eq。

详情

eq 可以是任何支持的偏微分方程(参见

支持方法的 pde docstring)。这可以是一个等式,或者是一个表达式,假设其等于 0。

f(x,y) 是一个关于两个变量的函数,其导数为

变量构成了偏微分方程。在许多情况下,没有必要提供这个;它将被自动检测(如果无法检测到,则会引发错误)。

hint 是你希望 pdsolve 使用的求解方法。

classify_pde(eq, f(x,y)) 用于获取一个偏微分方程的所有可能提示。默认提示 ‘default’ 将使用 classify_pde() 返回的第一个提示。请参阅下面的 Hints 部分,了解更多可用于 hint 的选项。

solvefun 是用于返回任意函数的约定。

由PDE求解器设置。如果用户未设置,则默认设置为F。

提示

除了各种求解方法外,还有一些元提示可以传递给 pdsolve():

“默认”:

这使用 classify_pde() 返回的第一个提示。这是 pdsolve() 的默认参数。

“全部”:

要使 pdsolve 应用所有相关的分类提示,请使用 pdsolve(PDE, func, hint=”all”)。这将返回一个包含提示:解决方案项的字典。如果某个提示导致 pdsolve 引发 NotImplementedError,该提示键的值将是引发的异常对象。该字典还将包含一些特殊键:

  • order: PDE 的阶数。另见 deutils.py 中的 ode_order()。

  • 默认值:将返回的解决方案。这是由首先出现在 classify_pde() 返回的元组中的提示生成的。

all_Integral

这与“all”相同,但如果提示也有相应的“_Integral”提示,它只返回“_Integral”提示。如果“all”导致 pdsolve() 挂起,因为积分困难或不可能,这很有用。这个元提示也将比“all”快得多,因为 integrate() 是一个昂贵的例程。

另请参阅 classify_pde() 的文档字符串以获取有关提示的更多信息,以及 pde 的文档字符串以获取所有支持的提示列表。

提示
  • 你可以这样声明一个未知函数的导数:

    >>> from sympy import Function, Derivative
    >>> from sympy.abc import x, y # x and y are the independent variables
    >>> f = Function("f")(x, y) # f is a function of x and y
    >>> # fx will be the partial derivative of f with respect to x
    >>> fx = Derivative(f, x)
    >>> # fy will be the partial derivative of f with respect to y
    >>> fy = Derivative(f, y)
    
  • 查看 test_pde.py 中的许多测试,这些测试也作为如何使用 pdsolve() 的示例集。

  • pdsolve 总是返回一个 Equality 类(除非提示是 “all” 或 “all_Integral”)。请注意,与 ODE 的情况不同,无法获得 f(x, y) 的显式解。

  • 执行 help(pde.pde_hintname) 以获取关于特定提示的更多帮助信息

示例

>>> from sympy.solvers.pde import pdsolve
>>> from sympy import Function, Eq
>>> from sympy.abc import x, y
>>> f = Function('f')
>>> u = f(x, y)
>>> ux = u.diff(x)
>>> uy = u.diff(y)
>>> eq = Eq(1 + (2*(ux/u)) + (3*(uy/u)), 0)
>>> pdsolve(eq)
Eq(f(x, y), F(3*x - 2*y)*exp(-2*x/13 - 3*y/13))
sympy.solvers.pde.classify_pde(
eq,
func=None,
dict=False,
*,
prep=True,
**kwargs,
)[源代码][源代码]

返回一个 PDE 可能的 pdsolve() 分类的元组。

元组是有序的,因此第一个项目是 pdsolve() 默认用于求解 PDE 的分类。通常,列表开头的分类会比末尾的分类更快地产生更好的解决方案,尽管总会有例外。要让 pdsolve 使用不同的分类,请使用 pdsolve(PDE, func, hint=<分类>)。另请参阅 pdsolve() 文档字符串,了解您可以使用的不同元提示。

如果 dict 为真,classify_pde() 将返回一个 hint:match 表达式项的字典。这是为 pdsolve() 的内部使用而设计的。请注意,由于字典的顺序是任意的,这很可能与元组中的顺序不同。

你可以通过执行 help(pde.pde_hintname) 来获取不同提示的帮助,其中 hintname 是提示的名称,不包括 “_Integral”。

请参阅 sympy.pde.allhints 或 sympy.pde 的 docstring,以获取 classify_pde 可以返回的所有支持的提示列表。

示例

>>> from sympy.solvers.pde import classify_pde
>>> from sympy import Function, Eq
>>> from sympy.abc import x, y
>>> f = Function('f')
>>> u = f(x, y)
>>> ux = u.diff(x)
>>> uy = u.diff(y)
>>> eq = Eq(1 + (2*(ux/u)) + (3*(uy/u)), 0)
>>> classify_pde(eq)
('1st_linear_constant_coeff_homogeneous',)
sympy.solvers.pde.checkpdesol(
pde,
sol,
func=None,
solve_for_func=True,
)[源代码][源代码]

检查给定的解是否满足偏微分方程。

pde 是偏微分方程,可以以方程或表达式的形式给出。sol 是待检查的解,也可以以方程或表达式的形式给出。如果未提供函数,则使用 deutils 中的辅助函数 _preprocess 来识别函数。

如果传递了一个解决方案序列,将使用相同类型的容器来返回每个解决方案的结果。

以下方法目前正在实施,以检查解决方案是否满足偏微分方程:

  1. 直接将解代入偏微分方程并检查。如果解尚未求解 f,则它将求解 f,前提是 solve_for_func 未设置为 False。

如果解满足偏微分方程(PDE),则返回一个元组 (True, 0)。否则返回一个元组 (False, expr),其中 expr 是解代入 PDE 后得到的值。然而,如果一个已知的解返回 False,这可能是因为 doit() 无法将其简化为零。

示例

>>> from sympy import Function, symbols
>>> from sympy.solvers.pde import checkpdesol, pdsolve
>>> x, y = symbols('x y')
>>> f = Function('f')
>>> eq = 2*f(x,y) + 3*f(x,y).diff(x) + 4*f(x,y).diff(y)
>>> sol = pdsolve(eq)
>>> assert checkpdesol(eq, sol)[0]
>>> eq = x*f(x,y) + f(x,y).diff(x)
>>> checkpdesol(eq, sol)
(False, (x*F(4*x - 3*y) - 6*F(4*x - 3*y)/25 + 4*Subs(Derivative(F(_xi_1), _xi_1), _xi_1, 4*x - 3*y))*exp(-6*x/25 - 8*y/25))

提示方法

这些函数是为内部使用而设计的。然而,它们包含了关于各种求解方法的有用信息。

sympy.solvers.pde.pde_1st_linear_constant_coeff_homogeneous(
eq,
func,
order,
match,
solvefun,
)[源代码][源代码]

求解具有常系数的线性齐次一阶偏微分方程。

这个偏微分方程的一般形式是

\[ \begin{align}\begin{aligned}a \frac{\partial f(x,y)}{\partial x} + b \frac{\partial f(x,y)}{\partial y} + c f(x,y) = 0\\a \frac{\partial f(x,y)}{\partial x} + b \frac{\partial f(x,y)}{\partial y} + c f(x,y) = 0\end{aligned}\end{align} \]

其中 \(a\)\(b\)\(c\) 是常数。

一般解的形式为:

\[f(x, y) = F(- a y + b x ) e^{- \frac{c (a x + b y)}{a^2 + b^2}}\]

并且可以在 SymPy 中通过 pdsolve 找到:

>>> from sympy.solvers import pdsolve
>>> from sympy.abc import x, y, a, b, c
>>> from sympy import Function, pprint
>>> f = Function('f')
>>> u = f(x,y)
>>> ux = u.diff(x)
>>> uy = u.diff(y)
>>> genform = a*ux + b*uy + c*u
>>> pprint(genform)
  d               d
a*--(f(x, y)) + b*--(f(x, y)) + c*f(x, y)
  dx              dy

>>> pprint(pdsolve(genform))
                         -c*(a*x + b*y)
                         ---------------
                              2    2
                             a  + b
f(x, y) = F(-a*y + b*x)*e

参考文献

  • Viktor Grigoryan, “偏微分方程” 数学 124A - 2010年秋季, 第7页

示例

>>> from sympy import pdsolve
>>> from sympy import Function, pprint
>>> from sympy.abc import x,y
>>> f = Function('f')
>>> pdsolve(f(x,y) + f(x,y).diff(x) + f(x,y).diff(y))
Eq(f(x, y), F(x - y)*exp(-x/2 - y/2))
>>> pprint(pdsolve(f(x,y) + f(x,y).diff(x) + f(x,y).diff(y)))
                      x   y
                    - - - -
                      2   2
f(x, y) = F(x - y)*e
sympy.solvers.pde.pde_1st_linear_constant_coeff(
eq,
func,
order,
match,
solvefun,
)[源代码][源代码]

求解具有常系数的线性一阶偏微分方程。

这个偏微分方程的一般形式是

\[ \begin{align}\begin{aligned}a \frac{\partial f(x,y)}{\partial x} + b \frac{\partial f(x,y)}{\partial y} + c f(x,y) = G(x,y)\\a \frac{\partial f(x,y)}{\partial x} + b \frac{\partial f(x,y)}{\partial y} + c f(x,y) = G(x,y)\end{aligned}\end{align} \]

其中 \(a\), \(b\)\(c\) 是常数,而 \(G(x, y)\) 可以是 \(x\)\(y\) 中的任意函数。

PDE 的一般解是:

\[\begin{split}f(x, y) = \left. \left[F(\eta) + \frac{1}{a^2 + b^2} \int\limits^{a x + b y} G\left(\frac{a \xi + b \eta}{a^2 + b^2}, \frac{- a \eta + b \xi}{a^2 + b^2} \right) e^{\frac{c \xi}{a^2 + b^2}}\, d\xi\right] e^{- \frac{c \xi}{a^2 + b^2}} \right|_{\substack{\eta=- a y + b x\\ \xi=a x + b y }}\, ,\end{split}\]

其中 \(F(\eta)\) 是一个任意的单值函数。可以使用 SymPy 中的 pdsolve 找到解:

>>> from sympy.solvers import pdsolve
>>> from sympy.abc import x, y, a, b, c
>>> from sympy import Function, pprint
>>> f = Function('f')
>>> G = Function('G')
>>> u = f(x, y)
>>> ux = u.diff(x)
>>> uy = u.diff(y)
>>> genform = a*ux + b*uy + c*u - G(x,y)
>>> pprint(genform)
  d               d
a*--(f(x, y)) + b*--(f(x, y)) + c*f(x, y) - G(x, y)
  dx              dy
>>> pprint(pdsolve(genform, hint='1st_linear_constant_coeff_Integral'))
          //          a*x + b*y                                             \         \|
          ||              /                                                 |         ||
          ||             |                                                  |         ||
          ||             |                                      c*xi        |         ||
          ||             |                                     -------      |         ||
          ||             |                                      2    2      |         ||
          ||             |      /a*xi + b*eta  -a*eta + b*xi\  a  + b       |         ||
          ||             |     G|------------, -------------|*e        d(xi)|         ||
          ||             |      |   2    2         2    2   |               |         ||
          ||             |      \  a  + b         a  + b    /               |  -c*xi  ||
          ||             |                                                  |  -------||
          ||            /                                                   |   2    2||
          ||                                                                |  a  + b ||
f(x, y) = ||F(eta) + -------------------------------------------------------|*e       ||
          ||                                  2    2                        |         ||
          \\                                 a  + b                         /         /|eta=-a*y + b*x, xi=a*x + b*y

参考文献

  • Viktor Grigoryan, “偏微分方程” 数学 124A - 2010年秋季, 第7页

示例

>>> from sympy.solvers.pde import pdsolve
>>> from sympy import Function, pprint, exp
>>> from sympy.abc import x,y
>>> f = Function('f')
>>> eq = -2*f(x,y).diff(x) + 4*f(x,y).diff(y) + 5*f(x,y) - exp(x + 3*y)
>>> pdsolve(eq)
Eq(f(x, y), (F(4*x + 2*y)*exp(x/2) + exp(x + 4*y)/15)*exp(-y))
sympy.solvers.pde.pde_1st_linear_variable_coeff(
eq,
func,
order,
match,
solvefun,
)[源代码][源代码]

求解具有变系数的线性一阶偏微分方程。该偏微分方程的一般形式为

\[a(x, y) \frac{\partial f(x, y)}{\partial x} + b(x, y) \frac{\partial f(x, y)}{\partial y} + c(x, y) f(x, y) = G(x, y)\]

其中 \(a(x, y)\)\(b(x, y)\)\(c(x, y)\)\(G(x, y)\)\(x\)\(y\) 中的任意函数。通过以下变换,此偏微分方程被转换为常微分方程:

  1. \(\xi\) 作为 \(x\)

  2. \(\eta\) 作为微分方程 \(\frac{dy}{dx} = -\frac{b}{a}\) 解中的常数

进行上述替换后,它简化为线性常微分方程

\[a(\xi, \eta)\frac{du}{d\xi} + c(\xi, \eta)u - G(\xi, \eta) = 0\]

可以使用 dsolve 来解决。

>>> from sympy.abc import x, y
>>> from sympy import Function, pprint
>>> a, b, c, G, f= [Function(i) for i in ['a', 'b', 'c', 'G', 'f']]
>>> u = f(x,y)
>>> ux = u.diff(x)
>>> uy = u.diff(y)
>>> genform = a(x, y)*u + b(x, y)*ux + c(x, y)*uy - G(x,y)
>>> pprint(genform)
                                     d                     d
-G(x, y) + a(x, y)*f(x, y) + b(x, y)*--(f(x, y)) + c(x, y)*--(f(x, y))
                                     dx                    dy

参考文献

  • Viktor Grigoryan, “偏微分方程” 数学 124A - 2010年秋季, 第7页

示例

>>> from sympy.solvers.pde import pdsolve
>>> from sympy import Function, pprint
>>> from sympy.abc import x,y
>>> f = Function('f')
>>> eq =  x*(u.diff(x)) - y*(u.diff(y)) + y**2*u - y**2
>>> pdsolve(eq)
Eq(f(x, y), F(x*y)*exp(y**2/2) + 1)

关于 pde 模块的信息

此模块包含 pdsolve() 及其使用的不同辅助函数。它深受 ode 模块的启发,因此基本基础设施保持不变。

本模块中的函数

这些是本模块中的用户函数:

  • pdsolve() - 解偏微分方程

  • classify_pde() - 将偏微分方程分类为 dsolve() 的可能提示。

  • pde_separate() - 在偏微分方程中分离变量,通过

    加法或乘法分离方法。

这些是本模块中的辅助函数:

  • pde_separate_add() - 用于搜索加性可分离解的辅助函数。

  • pde_separate_mul() - 用于搜索乘法分离的辅助函数

    可分离解。

当前实现的求解器方法

以下方法用于求解偏微分方程。有关每个方法的更多信息,请参阅各种 pde_hint() 函数的文档字符串(运行 help(pde)):

  • 一阶线性齐次偏微分方程与常系数。

  • 一阶线性常系数偏微分方程。

  • 具有变系数的1阶线性偏微分方程。