[PYTHON] Trouvez la solution numérique de l'équation différentielle ordinaire du second ordre avec scipy

introduction

En général, l'équation de mouvement est une équation différentielle du second ordre pour le temps du vecteur de position, vous devez donc résoudre ce problème afin de simuler le mouvement. Cependant, il existe des cas où une solution générale ne peut être facilement obtenue, auquel cas des calculs numériques seront effectués. Dans un tel cas, la méthode de recherche de la solution numérique de l'équation différentielle est implémentée dans un module appelé ode dans SciPy, calculons donc en l'utilisant.

scipy.integrate.ode http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html

Problème de réglage

Par souci de simplicité, considérons le problème de la chute libre à partir de la hauteur «h» par rapport aux points de qualité décrits par la masse «m» et la position «x». Ici, la résistance de l'air est négligeable et la force appliquée au point de qualité n'est que la gravité.

Équation du mouvement

D'après l'hypothèse ci-dessus, l'équation de mouvement est

m \ddot{x} = - g

Ce sera. Cependant, «g» est une constante de gravité. En outre, dans la convention de physique, les points au-dessus de la variable représentent la différenciation temporelle. S'il y a deux points, il s'agit d'un différentiel de second ordre.

Eh bien, cela peut clairement trouver une solution analytique,

x = - \frac{1}{2} g t^2 + h

Cependant, si l'heure y est insérée, il n'y a pas de source ni d'enfant, elle n'est donc utilisée qu'à des fins de comparaison avec la solution numérique.

Transformation de formule pour qu'elle puisse être résolue avec scipy

Eh bien, c'est le sujet principal. Puisque le module ode de SciPy (probablement comme n'importe quel autre) ne peut résoudre que des équations différentielles normales du premier ordre, il donne les transformations variables suivantes:

v := \dot{x}

Par conséquent, l'équation du mouvement est

\dot{x} = v
\dot{v} = - \frac{g}{m}

Ce sera. Ici, la différenciation est déplacée vers la gauche, mais ce n'est pas une question de hasard ou d'apparence, mais une limitation du module ode. Quant à l'équation différentielle linéaire, elle doit généralement avoir la forme suivante.

\frac{\mathrm{d}}{\mathrm{d}t}
\begin{bmatrix}
x_1 \\
\vdots \\
x_n
\end{bmatrix} =
\begin{bmatrix}
a_{11} & a_{12} & \dots & a_{1n} \\
\vdots & \ddots &  & \vdots \\
a_{n1} & \dots &  & a_{nn}
\end{bmatrix}
\begin{bmatrix}
x_1 \\
\vdots \\
x_n
\end{bmatrix} +
\begin{bmatrix}
b_1 \\
\vdots \\
b_n
\end{bmatrix}

Dans ce problème,

\frac{\mathrm{d}}{\mathrm{d}t}
\begin{bmatrix}
x_1 \\
x_2
\end{bmatrix} =
\begin{bmatrix}
0 & 1 \\
0 & 0
\end{bmatrix}
\begin{bmatrix}
x_1 \\
x_2
\end{bmatrix} +
\begin{bmatrix}
0 \\
- \frac{g}{m}
\end{bmatrix}

est. ** Dans le code ci-dessous, "première formule" et "deuxième formule" apparaissent dans la formule développée **. Ici, les conditions initiales suivantes sont obtenues à partir des descriptions "chute de hauteur" h "et" chute libre ".

x_1(0) = h
x_2(0) = 0

Maintenant que les deux sont sous la forme d'équations différentielles normales du premier ordre, ils peuvent enfin être résolus à l'aide du module ode.

Résolvez des équations différentielles normales avec scipy

Maintenant, faisons cela dans le code python. Cela dit, cela peut être fait presque mécaniquement. Voici le code complet.

#-*- coding:utf-8 -*-

import numpy as np
from scipy.integrate import odeint

g = 9.8     #Constante de gravité
m = 1.0     #Masse
h = 10      #Position initiale

def f(x, t):
    ret = [
        x[1],      #Côté droit de la formule 1
        -g / m     #Côté droit de la formule 2
    ]
    return ret


def main():
    #Etat initial
    x0 = [
        h,    #Conditions initiales de la première équation
        0     #Condition initiale de la deuxième équation
    ]

    #Intervalle de calcul
    #Les arguments sont dans l'ordre "heure de début", "heure de fin" et "incrémentation".
    t = np.arange(0, 10, 0.1)

    #Intégrer
    x = odeint(f, x0, t)

    #Afficher le résultat (imprimer tel quel pour le moment)
    print(x)


if __name__ == '__main__':
    main()

Si vous faites cela, vous obtiendrez une sortie similaire à ce qui suit:

$ python free_fall_sample.py
[[  1.00000000e+01   0.00000000e+00]
 [  9.95100000e+00  -9.80000000e-01]
 [  9.80400000e+00  -1.96000000e+00]
 [  9.55900000e+00  -2.94000000e+00]
...
 [ -4.60596000e+02  -9.60400000e+01]
 [ -4.70249000e+02  -9.70200000e+01]]

Il se présente sous la forme d'un double tableau et stocke un ensemble de solutions à chaque fois. L'ensemble des solutions est que le premier élément est la solution de la première équation et le deuxième élément est la solution de la deuxième équation (en bref, comme vous le voyez).

À titre de test, comparer la solution numérique à «t = 10» avec la valeur calculée à partir de la solution analytique,

Solution numérique= -4.70249000e+02 = -470.2 ...
Solution analytique= -9.8 / 2 * (10 * 10) + 10 = -480.0 ...

L'erreur est d'environ 10 [m](* M. Koryor a souligné qu'elle est en cours de correction. Veuillez consulter la section des commentaires pour plus de détails). Il existe plusieurs moyens d'améliorer cette précision, mais le plus simple est de réduire la taille du pas. Dans le code, c'est la partie:

    #Intervalle de calcul
    #Les arguments sont dans l'ordre "heure de début", "heure de fin" et "incrémentation".
    t = np.arange(0, 10, 0.01) # <=Changement

Avec ce changement, la solution numérique sera 479 et l'erreur sera d'environ 1,0.

Solution numérique= -4.79020490e+02 = -479.0 ...
Solution analytique= -9.8 / 2 * (10 * 10) + 10 = -480.0 ...

Si la réduction de la taille du pas ne fournit pas une précision suffisante ou prend trop de temps, envisagez un autre algorithme.

Considération

En passant, si vous regardez la solution qui est sortie sérieusement, vous pouvez voir que la position de la plaque est négative. C'est un état dans lequel les étudiants qui aspirent à une expérience de physique une fois, et les promesses sont enfoncées dans le sol. Parce qu'elle ignore les conditions aux limites et la répulsion du sol, la plaque perce le sol et accélère pour pénétrer de l'autre côté de la terre, mais pour éviter que cela se produise, la résistance de l'air et la répulsion du sol Besoin d'être défini. C'est un cas simple, vous le remarquerez donc tout de suite, mais s'il s'agit d'un cas compliqué, il est facile de l'ignorer, alors n'oubliez pas de regarder calmement les résultats une fois que vous l'avez résolu.

Résumé

J'ai trouvé la solution numérique de l'équation différentielle ordinaire avec scipy. Une fois que vous avez appris à l'utiliser, il est très facile et simple à utiliser, alors rappelez-vous si vous souhaitez résoudre l'équation du mouvement.

Recommended Posts

Trouvez la solution numérique de l'équation différentielle ordinaire du second ordre avec scipy
Trouvez la solution de l'équation d'ordre n avec python
[Calcul scientifique / technique par Python] Solution numérique d'une équation différentielle ordinaire du second ordre, problème de valeur initiale, calcul numérique
Analyse numérique des équations différentielles ordinaires avec l'odeint et l'ode de Scipy
Résolution du problème de la valeur initiale des équations différentielles ordinaires avec JModelica
L'histoire du calcul numérique des équations différentielles avec TensorFlow 2.0
Découvrez le jour par date / heure
[Calcul scientifique / technique par Python] Calcul numérique pour trouver la valeur de la dérivée (différentielle)
[Calcul scientifique / technique par Python] Solution analytique sympa pour résoudre des équations
Calculer la somme des valeurs uniques par tabulation croisée des pandas
Découvrez l'emplacement des packages installés avec pip
[Calcul scientifique / technique par Python] Solution numérique d'équations différentielles ordinaires du premier ordre, problème de valeur initiale, calcul numérique
J'ai essayé de trouver l'entropie de l'image avec python
Python - Solution numérique d'équation différentielle Méthode d'Euler et méthode de différence centrale et méthode Rungekutta
Découvrez la puissance de l'accélération avec NumPy / SciPy
Equation de mouvement avec sympy
Trouvez la valeur optimale de la fonction à l'aide d'un algorithme génétique (partie 2)
Calcul numérique d'équations aux dérivées partielles avec singularité (en utilisant les équations thermiques de type Hardy-Hénon à titre d'exemple)
Trouvez la définition de la valeur de errno
Trouvez la distance d'édition (distance de Levenshtein) avec python
J'ai remplacé le calcul numérique de Python par Rust et comparé la vitesse
Trouvez la broche inertielle et le moment d'inertie principal à partir du tenseur inertiel avec NumPy
Retrouvez les termes généraux de la séquence de Tribonacci en algèbre linéaire et Python
[Calcul scientifique / technique par Python] Résolution du problème de la valeur aux limites des équations différentielles ordinaires au format matriciel, calcul numérique