Как решить следующий вопрос, используя предоставленный метод Рунге-Кутта на python

Тело вопроса:

Парашютист массой м при вертикальном свободном падении испытывает силу аэродинамического сопротивления F = cy'² ('c раз y < / em> prime square '), где y измеряется вниз от начала падения, а y является функцией времени (y' обозначает производную от y по времени). Дифференциальное уравнение, описывающее падение:

y''=g-(c/m)y'²

(где g = 9,80665 м / с ^ 2; c = 0,2028 кг / м; m = 80 кг). И y (0) = y '(0) = 0, так как это свободное падение.

Задача: функция должна возвращать время падения x метров, где x - параметр функции. Значения g, c и m приведены ниже.

Функция Рунге-Кутта определяется следующим образом:

from numpy import *
def runge_kutta_4(F, x0, y0, x, h):
   '''
   Return y(x) given the following initial value problem:
   y' = F(x, y)
   y(x0) = y0 # initial conditions
   h is the increment of x used in integration
   F = [y'[0], y'[1], ..., y'[n-1]]
   y = [y[0], y[1], ..., y[n-1]]
   '''
   X = []
   Y = []
   X.append(x0)
   Y.append(y0)
   while x0 < x:
       k0 = F(x0, y0)
       k1 = F(x0 + h / 2.0, y0 + h / 2.0 * k0)
       k2 = F(x0 + h / 2.0, y0 + h / 2 * k1)
       k3 = F(x0 + h, y0 + h * k2)
       y0 = y0 + h / 6.0 * (k0 + 2 * k1 + 2.0 * k2 + k3)
       x0 += h
       X.append(x0)
       Y.append(y0)
   return array(X), array(Y)

И вот что я сделал до сих пор:

def prob_1_8(x)
    g = 9.80665  # m/s**2
    c = 0.2028  # kg/m
    m = 80  # kg

    def F(x, y):
        return array([
            y[1],
            g - (c / m) * ((y[1]) ** 2)
        ])

    X, Y = runge_kutta_4(F, 0, array([0, 0]), 5000, 1000)
    for i in range(len(X)):
        if X[i] == 5000:
            return Y[i]

Однако, когда я попытался напечатать prob

from numpy import *
def runge_kutta_4(F, x0, y0, x, h):
   '''
   Return y(x) given the following initial value problem:
   y' = F(x, y)
   y(x0) = y0 # initial conditions
   h is the increment of x used in integration
   F = [y'[0], y'[1], ..., y'[n-1]]
   y = [y[0], y[1], ..., y[n-1]]
   '''
   X = []
   Y = []
   X.append(x0)
   Y.append(y0)
   while x0 < x:
       k0 = F(x0, y0)
       k1 = F(x0 + h / 2.0, y0 + h / 2.0 * k0)
       k2 = F(x0 + h / 2.0, y0 + h / 2 * k1)
       k3 = F(x0 + h, y0 + h * k2)
       y0 = y0 + h / 6.0 * (k0 + 2 * k1 + 2.0 * k2 + k3)
       x0 += h
       X.append(x0)
       Y.append(y0)
   return array(X), array(Y)
8 (5000), число выглядело нелепо и отображалось:

RuntimeWarning: overflow encountered in double_scalars. 

Согласно предоставленному ответу, я должен получить значение, близкое к 84,8, при x = 5000. Может кто-то помочь мне с этим? Не знаю, в чем проблема и как ее исправить.


person Ziming Wang    schedule 22.11.2019    source источник


Ответы (1)


Обратите внимание на вызов функции X, Y = runge_kutta_4(F, 0, array([0, 0]), 5000, 1000). Вы интегрируете в течение 5000 sec > 1 hour с шагом 1000 sec > 16 min. Интуитивно понятно, что это будет неточно, поскольку большая часть ускорения произойдет в первые 10 секунд.


Тогда вопрос в том, что именно вы пытаетесь отфильтровать с помощью цикла. Это скорость после этого времени?


Предельная скорость - это когда правая сторона равна нулю, при vmax=sqrt(g*m/c) = 62.1972 = 223.91 km/h заявленное значение 84.8 не может быть достигнуто как скорость, начиная с состояния покоя. Время падения на расстояние x будет немного больше x/vmax, поэтому вы можете использовать tmax = 100+x/vmax в T, Y = runge_kutta_4(F, t0, y0, tmax, 1).


Интеграция с временными шагами в 1 секунду и поиск скорости после падения на 5000 метров дает результат 85 sec, расстояние 5013.33465614 m, скорость 62.1972 m/s, что, как и следовало ожидать, близко к предельной скорости.

Вы можете получить более точное значение времени, используя (обратную) линейную интерполяцию, тогда в момент времени около 84.786 sec вы достигнете расстояния 5000 m со скоростью 62.1972 m/s. Это опять же совместимо с заявленным значением результата, которое теперь является временем, а не скоростью.

person Lutz Lehmann    schedule 24.11.2019