test_pde.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. from sympy.core.function import (Derivative as D, Function)
  2. from sympy.core.relational import Eq
  3. from sympy.core.symbol import (Symbol, symbols)
  4. from sympy.functions.elementary.exponential import (exp, log)
  5. from sympy.functions.elementary.trigonometric import (cos, sin)
  6. from sympy.core import S
  7. from sympy.solvers.pde import (pde_separate, pde_separate_add, pde_separate_mul,
  8. pdsolve, classify_pde, checkpdesol)
  9. from sympy.testing.pytest import raises
  10. a, b, c, x, y = symbols('a b c x y')
  11. def test_pde_separate_add():
  12. x, y, z, t = symbols("x,y,z,t")
  13. F, T, X, Y, Z, u = map(Function, 'FTXYZu')
  14. eq = Eq(D(u(x, t), x), D(u(x, t), t)*exp(u(x, t)))
  15. res = pde_separate_add(eq, u(x, t), [X(x), T(t)])
  16. assert res == [D(X(x), x)*exp(-X(x)), D(T(t), t)*exp(T(t))]
  17. def test_pde_separate():
  18. x, y, z, t = symbols("x,y,z,t")
  19. F, T, X, Y, Z, u = map(Function, 'FTXYZu')
  20. eq = Eq(D(u(x, t), x), D(u(x, t), t)*exp(u(x, t)))
  21. raises(ValueError, lambda: pde_separate(eq, u(x, t), [X(x), T(t)], 'div'))
  22. def test_pde_separate_mul():
  23. x, y, z, t = symbols("x,y,z,t")
  24. c = Symbol("C", real=True)
  25. Phi = Function('Phi')
  26. F, R, T, X, Y, Z, u = map(Function, 'FRTXYZu')
  27. r, theta, z = symbols('r,theta,z')
  28. # Something simple :)
  29. eq = Eq(D(F(x, y, z), x) + D(F(x, y, z), y) + D(F(x, y, z), z), 0)
  30. # Duplicate arguments in functions
  31. raises(
  32. ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(x), u(z, z)]))
  33. # Wrong number of arguments
  34. raises(ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(x), Y(y)]))
  35. # Wrong variables: [x, y] -> [x, z]
  36. raises(
  37. ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(t), Y(x, y)]))
  38. assert pde_separate_mul(eq, F(x, y, z), [Y(y), u(x, z)]) == \
  39. [D(Y(y), y)/Y(y), -D(u(x, z), x)/u(x, z) - D(u(x, z), z)/u(x, z)]
  40. assert pde_separate_mul(eq, F(x, y, z), [X(x), Y(y), Z(z)]) == \
  41. [D(X(x), x)/X(x), -D(Z(z), z)/Z(z) - D(Y(y), y)/Y(y)]
  42. # wave equation
  43. wave = Eq(D(u(x, t), t, t), c**2*D(u(x, t), x, x))
  44. res = pde_separate_mul(wave, u(x, t), [X(x), T(t)])
  45. assert res == [D(X(x), x, x)/X(x), D(T(t), t, t)/(c**2*T(t))]
  46. # Laplace equation in cylindrical coords
  47. eq = Eq(1/r * D(Phi(r, theta, z), r) + D(Phi(r, theta, z), r, 2) +
  48. 1/r**2 * D(Phi(r, theta, z), theta, 2) + D(Phi(r, theta, z), z, 2), 0)
  49. # Separate z
  50. res = pde_separate_mul(eq, Phi(r, theta, z), [Z(z), u(theta, r)])
  51. assert res == [D(Z(z), z, z)/Z(z),
  52. -D(u(theta, r), r, r)/u(theta, r) -
  53. D(u(theta, r), r)/(r*u(theta, r)) -
  54. D(u(theta, r), theta, theta)/(r**2*u(theta, r))]
  55. # Lets use the result to create a new equation...
  56. eq = Eq(res[1], c)
  57. # ...and separate theta...
  58. res = pde_separate_mul(eq, u(theta, r), [T(theta), R(r)])
  59. assert res == [D(T(theta), theta, theta)/T(theta),
  60. -r*D(R(r), r)/R(r) - r**2*D(R(r), r, r)/R(r) - c*r**2]
  61. # ...or r...
  62. res = pde_separate_mul(eq, u(theta, r), [R(r), T(theta)])
  63. assert res == [r*D(R(r), r)/R(r) + r**2*D(R(r), r, r)/R(r) + c*r**2,
  64. -D(T(theta), theta, theta)/T(theta)]
  65. def test_issue_11726():
  66. x, t = symbols("x t")
  67. f = symbols("f", cls=Function)
  68. X, T = symbols("X T", cls=Function)
  69. u = f(x, t)
  70. eq = u.diff(x, 2) - u.diff(t, 2)
  71. res = pde_separate(eq, u, [T(x), X(t)])
  72. assert res == [D(T(x), x, x)/T(x),D(X(t), t, t)/X(t)]
  73. def test_pde_classify():
  74. # When more number of hints are added, add tests for classifying here.
  75. f = Function('f')
  76. eq1 = a*f(x,y) + b*f(x,y).diff(x) + c*f(x,y).diff(y)
  77. eq2 = 3*f(x,y) + 2*f(x,y).diff(x) + f(x,y).diff(y)
  78. eq3 = a*f(x,y) + b*f(x,y).diff(x) + 2*f(x,y).diff(y)
  79. eq4 = x*f(x,y) + f(x,y).diff(x) + 3*f(x,y).diff(y)
  80. eq5 = x**2*f(x,y) + x*f(x,y).diff(x) + x*y*f(x,y).diff(y)
  81. eq6 = y*x**2*f(x,y) + y*f(x,y).diff(x) + f(x,y).diff(y)
  82. for eq in [eq1, eq2, eq3]:
  83. assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
  84. for eq in [eq4, eq5, eq6]:
  85. assert classify_pde(eq) == ('1st_linear_variable_coeff',)
  86. def test_checkpdesol():
  87. f, F = map(Function, ['f', 'F'])
  88. eq1 = a*f(x,y) + b*f(x,y).diff(x) + c*f(x,y).diff(y)
  89. eq2 = 3*f(x,y) + 2*f(x,y).diff(x) + f(x,y).diff(y)
  90. eq3 = a*f(x,y) + b*f(x,y).diff(x) + 2*f(x,y).diff(y)
  91. for eq in [eq1, eq2, eq3]:
  92. assert checkpdesol(eq, pdsolve(eq))[0]
  93. eq4 = x*f(x,y) + f(x,y).diff(x) + 3*f(x,y).diff(y)
  94. eq5 = 2*f(x,y) + 1*f(x,y).diff(x) + 3*f(x,y).diff(y)
  95. eq6 = f(x,y) + 1*f(x,y).diff(x) + 3*f(x,y).diff(y)
  96. assert checkpdesol(eq4, [pdsolve(eq5), pdsolve(eq6)]) == [
  97. (False, (x - 2)*F(3*x - y)*exp(-x/S(5) - 3*y/S(5))),
  98. (False, (x - 1)*F(3*x - y)*exp(-x/S(10) - 3*y/S(10)))]
  99. for eq in [eq4, eq5, eq6]:
  100. assert checkpdesol(eq, pdsolve(eq))[0]
  101. sol = pdsolve(eq4)
  102. sol4 = Eq(sol.lhs - sol.rhs, 0)
  103. raises(NotImplementedError, lambda:
  104. checkpdesol(eq4, sol4, solve_for_func=False))
  105. def test_solvefun():
  106. f, F, G, H = map(Function, ['f', 'F', 'G', 'H'])
  107. eq1 = f(x,y) + f(x,y).diff(x) + f(x,y).diff(y)
  108. assert pdsolve(eq1) == Eq(f(x, y), F(x - y)*exp(-x/2 - y/2))
  109. assert pdsolve(eq1, solvefun=G) == Eq(f(x, y), G(x - y)*exp(-x/2 - y/2))
  110. assert pdsolve(eq1, solvefun=H) == Eq(f(x, y), H(x - y)*exp(-x/2 - y/2))
  111. def test_pde_1st_linear_constant_coeff_homogeneous():
  112. f, F = map(Function, ['f', 'F'])
  113. u = f(x, y)
  114. eq = 2*u + u.diff(x) + u.diff(y)
  115. assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
  116. sol = pdsolve(eq)
  117. assert sol == Eq(u, F(x - y)*exp(-x - y))
  118. assert checkpdesol(eq, sol)[0]
  119. eq = 4 + (3*u.diff(x)/u) + (2*u.diff(y)/u)
  120. assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
  121. sol = pdsolve(eq)
  122. assert sol == Eq(u, F(2*x - 3*y)*exp(-S(12)*x/13 - S(8)*y/13))
  123. assert checkpdesol(eq, sol)[0]
  124. eq = u + (6*u.diff(x)) + (7*u.diff(y))
  125. assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
  126. sol = pdsolve(eq)
  127. assert sol == Eq(u, F(7*x - 6*y)*exp(-6*x/S(85) - 7*y/S(85)))
  128. assert checkpdesol(eq, sol)[0]
  129. eq = a*u + b*u.diff(x) + c*u.diff(y)
  130. sol = pdsolve(eq)
  131. assert checkpdesol(eq, sol)[0]
  132. def test_pde_1st_linear_constant_coeff():
  133. f, F = map(Function, ['f', 'F'])
  134. u = f(x,y)
  135. eq = -2*u.diff(x) + 4*u.diff(y) + 5*u - exp(x + 3*y)
  136. sol = pdsolve(eq)
  137. assert sol == Eq(f(x,y),
  138. (F(4*x + 2*y)*exp(x/2) + exp(x + 4*y)/15)*exp(-y))
  139. assert classify_pde(eq) == ('1st_linear_constant_coeff',
  140. '1st_linear_constant_coeff_Integral')
  141. assert checkpdesol(eq, sol)[0]
  142. eq = (u.diff(x)/u) + (u.diff(y)/u) + 1 - (exp(x + y)/u)
  143. sol = pdsolve(eq)
  144. assert sol == Eq(f(x, y), F(x - y)*exp(-x/2 - y/2) + exp(x + y)/3)
  145. assert classify_pde(eq) == ('1st_linear_constant_coeff',
  146. '1st_linear_constant_coeff_Integral')
  147. assert checkpdesol(eq, sol)[0]
  148. eq = 2*u + -u.diff(x) + 3*u.diff(y) + sin(x)
  149. sol = pdsolve(eq)
  150. assert sol == Eq(f(x, y),
  151. F(3*x + y)*exp(x/5 - 3*y/5) - 2*sin(x)/5 - cos(x)/5)
  152. assert classify_pde(eq) == ('1st_linear_constant_coeff',
  153. '1st_linear_constant_coeff_Integral')
  154. assert checkpdesol(eq, sol)[0]
  155. eq = u + u.diff(x) + u.diff(y) + x*y
  156. sol = pdsolve(eq)
  157. assert sol.expand() == Eq(f(x, y),
  158. x + y + (x - y)**2/4 - (x + y)**2/4 + F(x - y)*exp(-x/2 - y/2) - 2).expand()
  159. assert classify_pde(eq) == ('1st_linear_constant_coeff',
  160. '1st_linear_constant_coeff_Integral')
  161. assert checkpdesol(eq, sol)[0]
  162. eq = u + u.diff(x) + u.diff(y) + log(x)
  163. assert classify_pde(eq) == ('1st_linear_constant_coeff',
  164. '1st_linear_constant_coeff_Integral')
  165. def test_pdsolve_all():
  166. f, F = map(Function, ['f', 'F'])
  167. u = f(x,y)
  168. eq = u + u.diff(x) + u.diff(y) + x**2*y
  169. sol = pdsolve(eq, hint = 'all')
  170. keys = ['1st_linear_constant_coeff',
  171. '1st_linear_constant_coeff_Integral', 'default', 'order']
  172. assert sorted(sol.keys()) == keys
  173. assert sol['order'] == 1
  174. assert sol['default'] == '1st_linear_constant_coeff'
  175. assert sol['1st_linear_constant_coeff'].expand() == Eq(f(x, y),
  176. -x**2*y + x**2 + 2*x*y - 4*x - 2*y + F(x - y)*exp(-x/2 - y/2) + 6).expand()
  177. def test_pdsolve_variable_coeff():
  178. f, F = map(Function, ['f', 'F'])
  179. u = f(x, y)
  180. eq = x*(u.diff(x)) - y*(u.diff(y)) + y**2*u - y**2
  181. sol = pdsolve(eq, hint="1st_linear_variable_coeff")
  182. assert sol == Eq(u, F(x*y)*exp(y**2/2) + 1)
  183. assert checkpdesol(eq, sol)[0]
  184. eq = x**2*u + x*u.diff(x) + x*y*u.diff(y)
  185. sol = pdsolve(eq, hint='1st_linear_variable_coeff')
  186. assert sol == Eq(u, F(y*exp(-x))*exp(-x**2/2))
  187. assert checkpdesol(eq, sol)[0]
  188. eq = y*x**2*u + y*u.diff(x) + u.diff(y)
  189. sol = pdsolve(eq, hint='1st_linear_variable_coeff')
  190. assert sol == Eq(u, F(-2*x + y**2)*exp(-x**3/3))
  191. assert checkpdesol(eq, sol)[0]
  192. eq = exp(x)**2*(u.diff(x)) + y
  193. sol = pdsolve(eq, hint='1st_linear_variable_coeff')
  194. assert sol == Eq(u, y*exp(-2*x)/2 + F(y))
  195. assert checkpdesol(eq, sol)[0]
  196. eq = exp(2*x)*(u.diff(y)) + y*u - u
  197. sol = pdsolve(eq, hint='1st_linear_variable_coeff')
  198. assert sol == Eq(u, F(x)*exp(-y*(y - 2)*exp(-2*x)/2))