简体   繁体   中英

Solving Non-Linear Differential Equation Sympy

This code only works for solving the differential equation v_equation if v(t) isn't squared. When I squared it it returned the error PolynomialDivisionFailed. Is there another way of doing this with Sympy or should I find a different python package for doing these sorts of calculations.

from sympy import *
from matplotlib import pyplot as plt
import numpy as np

m = float(raw_input('Mass:\n> '))
g = 9.8
k = float(raw_input('Drag Coefficient:\n> '))
f1 = g * m
t = Symbol('t')
v = Function('v')
v_equation = dsolve(f1 - k * (v(t) ** 2) - m * Derivative(v(t)), 0)
C1 = Symbol('C1')
C1_ic = solve(v_equation.rhs.subs({t:0}),C1)[0]
v_equation = v_equation.subs({C1:C1_ic})

func = lambdify(t, v_equation.rhs,'numpy')

From my experience with symbolic math packages, I would not recommend performing (symbolic) calculations using floating point constants. It is better to define equations using symbolic constants, perform calculations as far as possible, and then substitute with numerical values.

With this approach, Sympy can provide a solution for this DE

First, define symbolic constants. To aid calculations, note that we can provide additional information about these constants (eg, real, positive, etc)

import sympy as sp

t = sp.symbols('t', real = True)
g, k, m = sp.symbols('g, k, m', real = True, positive = True)
v = sp.Function('v')

The symbolic solution for the DE can be obtained as follows

f1 = g * m
eq = f1 - k * (v(t) ** 2) - m * sp.Derivative(v(t))
sol = sp.dsolve(eq,v(t)).simplify()

The solution sol will be a function of k , m , g , and a constant C1 . In general, there will be two, complex C1 values corresponding to the initial condition. However, both values of C1 result in the same (real-valued) solution when substituted in sol .

Note that if you don't need a symbolic solution, a numerical ODE solver, such as Scipy's odeint , may be used. The code would be the following (for an initial condition 0 ):

from scipy.integrate import odeint

def fun(v, t, m, k, g):
    return (g*m - k*v**2)/m

tn = np.linspace(0, 10, 101)
soln = odeint(fun, 0, tn, args=(1000, 0.2, 9.8))

soln is an array of samples v(t) corresponding to the tn elements

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM