Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Numerično reševanje diferencialnih enačb - začetni problem

Fakulteta za strojništvo, Univerza v Ljubljani

Uvod

Zapis (ene) diferencialne enačbe

Predpostavimo, da je mogoče diferencialno enačbo prvega reda zapisati v eksplicitni obliki:

y′=f(t,y),y'=f(t, y),

kjer je f(t,y)f(t, y) podana funkcija in velja y′=dy/dty'=dy/dt.

Dodatno je podan začetni pogoj:

y(t0)=y0.y(t_0)=y_0.

Cilj reševanja diferencialne enačbe je izračunati funkcijo y(t)y(t), ki reši zgoraj definiran začetni problem. Ob določenih pogojih funkcije f(t,y)f(t, y) ima začetni problem enolično rešitev na intervalu, ki vsebuje t0t_0.

Pri numeričnem reševanju vedno računamo tabelo funkcije y(ti)y(t_i), ki reši dan začetni problem. Pri tem so vozlišča tit_i običajno ekvidistantna:

t0,t0+h,t0+2h,…t_0, t_0+h, t_0+2h,\dots

in hh imenujemo (časovni) korak (integracije).

Tukaj si bomo pogledali nekatere numerične metode za reševanje diferencialnih enačb pri začetnem pogoju.

Eulerjeva metoda

Eksplicitna Eulerjeva metoda temelji na razvoju funkcije yy v Taylorjevo vrsto:

y(t+h)=y(t)+f(t,y(t)) h+O(h2).y(t+h)=y(t)+f(t, y(t))\,h + \mathcal{O}(h^2).

Naredimo napako metode O(h2)\mathcal{O}(h^2), ker zanemarimo odvode drugega in višjih redov; sedaj lahko ob znani vrednosti y(t)y(t) in odvodu y′(t)=f(t,y)y'(t)=f(t,y) ocenimo vrednosti pri naslednjem časovnem koraku t+ht+h. Ko imamo enkrat znane vrednosti pri t+ht+h, ponovimo postopek!

Koraki Eulerjeve metode:

  1. Postavimo i=0i=0, t0t_0, y0=y(t0)y_0=y(t_0).

  2. Izračun vrednosti funkcije pri ti+1=ti+ht_{i+1}=t_i+h: yi+1=yi+f(ti,yi) h.y_{i+1}= y_i + f(t_i, y_i)\,h.

  3. i=i+1i=i+1 in nadaljevanje v koraku 2.

Diferencialno enačbo rešujemo na intervalu [t0,tn][t_0,t_n] in velja h=(tn−t0)/nh=(t_n-t_0)/n. nn je število integracijskih korakov (kolikokrat izvedemo korak 2 v zgornjem algoritmu).

Numerična rešitev začetnega problema:

y0,y1,y2,…,yny_0, y_1, y_2,\dots, y_{n}

pri vrednostih neodvisne spremenljivke:

t0,t1,t2 … tn.t_0, t_1, t_2\, \dots \, t_n.
Loading...

Napaka Eulerjeve metode

Napaka Eulerjeve metode na vsakem koraku je reda O(h2)\mathcal{O}(h^2).

Ker na intervalu od t0t_0 do tnt_n tako napako naredimo nn-krat, je kumulativna napaka n O(h2)=tn−t0h O(h2)=O(h)n\,\mathcal{O}(h^2)=\frac{t_n-t_0}{h}\,\mathcal{O}(h^2)=\mathcal{O}(h).

Lokalno je napaka drugega reda, globalno pa je napaka prvega reda in ker je Eulerjeva metoda tako nenatančna jo redko uporabljamo v praksi!

Ocena napake

Točna rešitev y(tn)y(t_n) pri velikosti koraka hh je:

y(tn)=yn,h+Eh,y(t_n)=y_{n,h}+E_h,

kjer je yn,hy_{n,h} numerični približek in EhE_h napaka metode. Ker je globalna napaka prvega reda, lahko napako zapišemo kot:

Eh=k h.E_h=k\,h.

Podobno lahko za velikost koraka 2h2h zapišemo:

y(tn)=yn,2h+E2h,y(t_n)=y_{n,2h}+E_{2h},

kjer je yn,2hy_{n,2h} numerični približek in E2hE_{2h} napaka metode:

E2h=k 2 h.E_{2h}=k\,2\,h.

Ob predpostavki, da je konstanta kk pri koraku hh in koraku 2h2h enaka, lahko določimo oceno napake pri boljšem približku EhE_h. Očitno velja:

yn,h+k h=yn,2h+2 k hy_{n,h}+k\,h=y_{n,2h}+2\,k\,h

nato določimo oceno napake:

Eh=k h=yn,h−yn,2h.E_h=k\,h=y_{n,h}-y_{n,2h}.

Komentar na implicitno Eulerjevo metodo

Pri eksplicitni Eulerjevi metodi računamo rešitev pri ti+1t_{i+1} iz izračunane vrednosti pri tit_i.

V kolikor bi nastopala neznana vrednost rešitve pri ti+1t_{i+1}, to je yi+1y_{i+1}, tudi na desni strani, bi govorili o implicitni Eulerjevi metodi (ali povratni Eulerjevi metodi):

yi+1=yi+f(ti+1,yi+1) h.y_{i+1}=y_i+f(t_{i+1}, y_{i+1})\,h.

Ker se iskana vrednost yi+1y_{i+1} nahaja na obeh straneh enačbe, moramo za določitev yi+1y_{i+1} rešiti (nelinearno) enačbo. Prednost implicitne Eulerjeve metode je, da je bolj stabilna (npr. v primeru togih sistemov, ki jih bomo spoznali pozneje) kakor eksplicitna oblika, vendar pa je numerično bolj zahtevna (zaradi računanja rešitve enačbe).

Numerična implementacija

Najprej uvozimo potrebne knjižnice:

Nato definirajmo Eulerjevo metodo:

Pripravimo funkcijo za oceno napake (v numeričnem smislu bi bilo bolje oceno napake vključiti v funkcijo euler, vendar jo zaradi jasnosti predstavimo ločeno):

Numerični zgled

Kot primer rešimo diferencialno enačbo, ki opisuje padanje telesa, ki je izpostavljeno sili teže in zračnemu uporu: Padanje telesa

Glede na II. Newtonov zakon, lahko zapišemo diferencialno enačbo:

m g−c v=m v′,m\,g-c\,v=m\,v',

kjer je mm masa, gg gravitacijski pospešek, cc koeficient zračnega upora in vv hitrost. Diferencialno enačbo bi hoteli rešiti glede na začetni pogoj:

v(0)=0 m/s.v(0)=0\,\textrm{m/s}.

Funkcija desne strani / prvega odvoda f(t,y)f(t,y) je:

f(t,y)=g−c ymf(t,y)=g-c\, \frac{y}{m}

in začetni pogoj:

y0=0.y_0=0.

Definirajmo funkcijo desnih strani:

Definirajmo začetni pogoj in časovni vektor, kjer nas zanima rezultat:

array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])

Kličemo funkcijo euler za izračun vrednosti yy (hitrost vv):

array([ 0. , 9.81 , 14.715 , 17.1675 , 18.39375 , 19.006875 , 19.3134375 , 19.46671875, 19.54335938, 19.58167969, 19.60083984])

Prikažemo rezultat:

<Figure size 640x480 with 1 Axes>

Preverimo sedaj vpliv časovnega koraka:

<Figure size 640x480 with 1 Axes>

Opazimo, da se numerična napaka pri spremembi koraka iz 1 na 0,1 bistveno zmanjša!

Ocenimo še napako pri 100 in 1000 odsekih:

Loading...
Loading...

Ko smo korak zmanjšali na desetino, se je proporcionalno zmanjšala tudi napaka (prvi red napake).

Poglejmo še primer, ko je zračni upor c argument funkcije euler in je prek **kwargs posredovan v funkcijo f_zračni_upor():

<Figure size 640x480 with 1 Axes>

Metoda Runge-Kutta drugega reda

Eulerjeva metoda je prvega reda (prvega reda je namreč globalna napaka O(h)\mathcal{O}(h)). Če bi želeli izpeljati metodo drugega reda napake, bi si morali pomagati z razvojem y(t+h)y(t+h) v Taylorjevo vrsto, kjer bomo zanemarili tretji in višje odvode:

y(t+h)=y(t)+y′(t) h+12y′′(t) h2+O(h3).y(t+h)=y(t)+y'(t)\,h + \frac{1}{2}y''(t)\,h^2+\mathcal{O}(h^3).

Lokalna napaka metode bo tako tretjega reda, globalna pa drugega reda.

Uporabimo zamenjavi y′(t)=f(t,y)y'(t)=f(t,y) in y′′(t)=f′(t,y)y''(t)=f'(t,y):

y(t+h)=y(t)+f(t,y) h+12f′(t,y) h2+O(h3).y(t+h)=y(t)+f(t,y)\,h + \frac{1}{2}f'(t,y)\,h^2+\mathcal{O}(h^3).

Ker je desna stran f(t,y)f(t,y) odvisna od neodvisne tt in odvisne spremenljivke yy, moramo uporabiti implicitno odvajanje:

f′(t,y)=∂f(t,y)∂t+∂f(t,y)∂y dydt⏟y′=f(t,y)=∂f(t,y)∂t+∂f(t,y)∂y f(t,y).f'(t,y)=\frac{\partial f(t,y)}{\partial t}+\frac{\partial f(t,y)}{\partial y}\,\underbrace{\frac{\textrm{d} y}{\textrm{d} t}}_{y'=f(t,y)} =\frac{\partial f(t,y)}{\partial t}+\frac{\partial f(t,y)}{\partial y}\,{f(t, y)}.

Vstavimo v izraz za Taylorjevo vrsto:

y(t+h)Taylor=y(t+h)=y(t)+f(t,y) h+12 (∂f(t,y)∂t+∂f(t,y)∂y f(t,y)) h2.y(t+h)_{\textrm{Taylor}}=y(t+h)=y(t)+f(t,y)\,h + \frac{1}{2}\,{\LARGE(} \frac{\partial f(t,y)}{\partial t}+\frac{\partial f(t,y)}{\partial y}\,{f(t, y)} {\LARGE)}\,h^2.

Kot je razvidno iz zgornjega izraza, potrebujemo dodatne odvode. To predstavlja določeno težavo, ki se ji lahko izognemo na različne načine; v nadaljevanju si bomo pogledali pristop Runge-Kutta. Ker bomo zgornji izraz pozneje še potrebovali, smo ga tukaj poimenovali y(t+h)Taylory(t+h)_{\textrm{Taylor}}.

Ideja pristopa Runge-Kutta

Zgornjo dilemo metoda Runge-Kutta (razvita leta 1901) rešuje z idejo, ki smo jo sicer že srečali pri Gaussovi integraciji: točnejšo rešitev poskuša najti z uteženo dodatno vrednostjo funkcije ff:

y(t+h)Runge-Kutta=y(t)+c0 f(t,y) h+c1f(t+p h,y+q h f(t,y))⏟A h.y(t+h)_{\textrm{Runge-Kutta}}=y(t)+c_0\,f\left(t,y\right)\,h +c_1 \underbrace{f{\large(}t+p\,h,y+q\,h\,f(t,y){\large)}}_{A}\,h.

kjer so c0c_0, c1c_1, pp in qq neznane konstante (načeloma od 0 do vključno 1). Če bi v zgornjem izrazu uporabili c1=0c_1=0, bi izpeljali metodo prvega reda; z dodatno funkcijsko vrednostjo (AA) pa se bo izkazalo, da bomo izpeljali metodo drugega reda.

Iskanje neznanih konstant c0c_0, c1c_1, pp, qq nadaljujemo z zapisom AA v obliki Taylorjeve vrste prvega reda:

f(t+p h,y+q h f(t,y))=f(t,y)+∂f(t,y)∂t (p h)+∂f(t,y)∂y (q h f(t,y))⏟B.f{\large(}t+p\,h,y+q\,h\,f(t,y){\large)}= \underbrace{ f{\large(}t,y{\large)}+ \frac{\partial f(t,y)}{\partial t}\,\left(p\,h\right)+ \frac{\partial f(t,y)}{\partial y}\,\left(q\,h\,f(t, y)\right) }_{B}.

Vstavimo sedaj izpeljani BB nazaj v izraz za y(t+h)Runge-Kuttay(t+h)_{\textrm{Runge-Kutta}}:

y(t+h)Runge-Kutta=y(t)+c0 f(t,y) h+c1(f(t,y)+∂f(t,y)∂t (p h)+∂f(t,y)∂y (q h f(t,y))) h.y(t+h)_{\textrm{Runge-Kutta}}=y(t)+c_0\,f\left(t,y\right)\,h +c_1 {\LARGE(} f{\large(}t,y{\large)}+ \frac{\partial f(t,y)}{\partial t}\,\left(p\,h\right)+ \frac{\partial f(t,y)}{\partial y}\,\left(q\,h\,f(t, y)\right) {\LARGE)} \,h.

Nadaljujemo z izpeljevanjem in enačbo preoblikujemo, da bo podobna zgoraj izpeljani s Taylorjevo vrsto y(t+h)Taylory(t+h)_{\textrm{Taylor}}:

y(t+h)Runge-Kutta=y(t)+(c0+c1) f(t,y) h+12(∂f(t,y)∂t 2 c1 p+2 c1 q ∂f(t,y)∂y f(t,y)) h2.y(t+h)_{\textrm{Runge-Kutta}}=y(t)+(c_0+c_1)\,f\left(t,y\right)\,h +\frac{1}{2} {\LARGE(} \frac{\partial f(t,y)}{\partial t}\,2\,c_1\,p+ 2\,c_1\,q\,\frac{\partial f(t,y)}{\partial y}\,f(t, y) {\LARGE)} \,h^2.

Primerjajmo sedaj z zgoraj izpeljanim izrazom:

y(t+h)Taylor=y(t)+f(t,y) h+12 (∂f(t,y)∂t+∂f(t,y)∂y f(t,y)) h2.y(t+h)_{\textrm{Taylor}}=y(t)+f(t,y)\,h + \frac{1}{2}\,{\LARGE(} \frac{\partial f(t,y)}{\partial t}+\frac{\partial f(t,y)}{\partial y}\,{f(t, y)} {\LARGE)}\,h^2.

Ugotovimo, da za enakost mora veljati:

c0+c1=1,2 c1 p=1,2 c1 q=1.c_0+c_1=1,\qquad 2\,c_1\,p=1,\qquad 2\,c_1\,q=1.

Imamo torej tri enačbe in štiri neznanke. Eno od konstant si tako lahko poljubno izberemo, ostale tri pa izračunamo. Če na primer izberemo c0=0c_0=0, bi to imenovali spremenjena Eulerjeva metoda in bi ostali parametri bili: c1=1c_1=1, p=q=1/2p=q=1/2. Izbira parametrov nima bistvenega vpliva na rešitev. Sicer pa velja omeniti, da tudi metodo Runge-Kutta drugega reda redko uporabljamo, saj obstajajo boljše metode.

Parametre c0c_0, c1c_1, pp in qq vstavimo v prvo enačbo tega poglavja. Ko je definiran začetni čas t0t_0 in začetni pogoj y0y_0, uporabimo metodo Runge-Kutta drugega reda:

yi+1=yi+f(ti+12 h,yi+12 h f(ti,yi)) h.y_{i+1} = y_i + f\left(t_i+\frac{1}{2}\,h, y_i+\frac{1}{2}\,h\,f(t_i,y_i)\right)\,h.

Metoda Runge-Kutta četrtega reda

Podobno kot smo izpeljali metodo Runge-Kutta drugega reda, se izpelje metodo Runge-Kutta četrtega reda. Tudi pri metodi četrtega reda obstaja več različic in kot metoda Runge-Kutta četrtega reda razumemo naslednjo metodo:

yi+1=yi+16(k0+2 k1+2 k2+k3),y_{i+1}=y_i+\frac{1}{6}(k_0+2\,k_1+2\,k_2+k_3),

kjer so:

k0=h f(ti,yi)k1=h f(ti+h2,yi+k02)k2=h f(ti+h2,yi+k12)k3=h f(ti+h,yi+k2).\begin{aligned} k_0&=h\,f(t_i,y_i)\\ k_1&=h\,f\left(t_i+\frac{h}{2},y_i+\frac{k_0}{2}\right)\\ k_2&=h\,f\left(t_i+\frac{h}{2},y_i+\frac{k_1}{2}\right)\\ k_3&=h\,f\left(t_i+h,y_i+k_2\right). \end{aligned}

Koraki metode Runge-Kutta četrtega reda so:

  1. Določitev i=0i=0 in t0t_0, y0=y(t0)y_0=y(t_0),

  2. Izračun koeficientov: k0k_0, k1k_1, k2k_2, k3k_3,

  3. Izračun vrednosti rešitve diferencialne enačbe pri ti+1=ti+ht_{i+1}=t_i+h: yi+1=yi+16(k0+2 k1+2 k2+k3),\quad y_{i+1}=y_i+\frac{1}{6}(k_0+2\,k_1+2\,k_2+k_3),

  4. i=i+1i=i+1 in nadaljevanje v koraku 2.

Napaka metode Runge-Kutta četrtega reda

Metodo Runge-Kutta četrtega reda imenujemo tako zato, ker ima lokalno napako petega reda O(h5)\mathcal{O}(h^5), vendar pa to napako naredimo nn-krat, zato je globalna napaka četrtega reda O(h4)\mathcal{O}(h^4).

Ocena napake

Točen rezultat y(tn)y(t_n) pri velikosti koraka hh je:

y(tn)=yn,h+Eh,y(t_n)=y_{n,h}+E_h,

kjer je yn,hy_{n,h} numerični približek rešitve in EhE_h napaka metode. Ker je globalna napaka četrtega reda, lahko napako zapišemo tako:

Eh=k h4.E_h=k\,h^4.

Podobno lahko za velikost koraka 2h2h zapišemo:

y(tn)=yn,2h+E2h,y(t_n)=y_{n,2h}+E_{2h},

kjer je yn,2hy_{n,2h} numerični približek rešitve in E2hE_{2h} napaka metode:

E2h=k (2 h)4=16 k h4.E_{2h}=k\,(2\,h)^4=16\,k\,h^4.

Ob predpostavki, da je konstanta kk pri koraku hh in koraku 2h2h enaka, lahko izračunamo oceno napake pri boljšem približku EhE_h.

Najprej je res:

yn,h+k h4=yn,2h+16 k h4,y_{n,h}+k\,h^4=y_{n,2h}+16\,k\,h^4,

sledi:

15 k h4=yn,h−yn,2h15\,k\,h^4=y_{n,h}-y_{n,2h}

in nato določimo oceno napake natančnejše rešitve:

Eh=yn,h−yn,2h15.E_h=\frac{y_{n,h}-y_{n,2h}}{15}.

Numerična implementacija

Funkcija za oceno napake:

Numerični zgled

Poglejmo sedaj primer izračuna hitrosti padajoče mase:

Podajmo začetni pogoj in časovni vektor, kjer nas zanima rezultat:

array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])

Za primerjavo izračunajmo rešitev s funkcijo euler ter runge_kutta_4:

Prikažemo rezultat:

<Figure size 640x480 with 1 Axes>

Poglejmo še numerično napako:

Loading...
Loading...

Pri zmanjšanju koraka na desetino, se je napaka zmanjšala za približno 104-krat (kar ustreza pričakovanjem za metodo četrtega reda).

Uporaba scipy za reševanje navadnih diferencialnih enačb

Paket scipy ima implementiranih veliko numeričnih metod za reševanje začetnih problemov navadnih diferencialnih enačb. Tukaj si bomo ogledali funkcijo scipy.integrate.solve_ivp, ki je primerna za večino začetnih problemov.

scipy.integrate.solve_ivp

Sintaksa za uporabo (IVP - angl. Initial Value Problem):

scipy.integrate.solve_ivp(fun, t_span, y0, method='RK45', 
                          t_eval=None, dense_output=False, 
                          events=None, vectorized=False, 
                          args=None, **options)

Pojasnilo vseh argumentov je v dokumentaciji, tukaj bomo izpostavili nekatere:

  • fun je desna stran (func(t, y...)),

  • t_span terka (t0, tf), ki definira začetni t0 in končni čas tf,

  • y0 seznam začetne(ih) vrednosti,

  • method definira numerično metodo (privzeta je eksplicitna ‘RK45’, za toge sisteme pa so boljše: ‘Radau’, ‘BDF’, ‘LSODA’),

  • t_eval uporabimo, če želimo rešitve ob določenih vrednosti neodvisne spremenljivke,

  • dense_output ali se pripravi tudi zvezna rešitev, privzeto False,

  • events za sledenje dogodkov, ki ustavijo reševanje začetnega problema (npr. ko se masa dotakne tal in je relativna razdalja do tal nič).

  • args za posredovanje argumentov v funkcijo fun (glejte primer spodaj).

Rezultat klicanja solve_ivp je objekt z atributi (izbrani):

  • t vrednosti neodvisne spremenljivke pri katerih je izračunan rezultat,

  • y rezultat,

  • sol funkcija zvezne rešitve (samo v primeru dense_output=True)

  • success je True, če je bila rešitev uspešno izračunana ali prekinjena zaradi dogodka (events).

Numerični zgled

Definirajmo začetni pogoj in časovni vektor, kjer nas zanima rezultat (prikažemo samo prvih deset elementov):

array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])

Argumente (g=9.81, m=1., c=0.4) v funkcijo posredujemo prek parametra args:

Lahko bi pa uporabili tudi lambda izraza (dokumentacija):

y_ivp = solve_ivp(lambda t,y: f_zračni_upor(t, y, c=0.4), t_span=(t[0], t[-1]), y0=[v0])

Zgoraj uporabljen lambda izraz lambda t, y: f_zračni_upor(t, y, c=0.4) je ekvivalenten:

def ime_funkcije(t, y):
    return f_zračni_upor(t, y, c=0.4)

Poglejmo rezultat:

message: The solver successfully reached the end of the integration interval. success: True status: 0 t: [ 0.000e+00 1.000e-04 1.100e-03 1.110e-02 1.111e-01 1.111e+00 2.982e+00 5.236e+00 7.948e+00 1.000e+01] y: [[ 0.000e+00 9.810e-04 1.079e-02 1.086e-01 1.066e+00 8.800e+00 1.708e+01 2.150e+01 2.350e+01 2.407e+01]] sol: None t_events: None y_events: None nfev: 56 njev: 0 nlu: 0

Ker je solve_ivp že pripravljen za sistem navadnih diferencialnih enačb prvega reda, je rezultat podan v dveh dimenzijah. Iskan rezultat je torej: y_ivp.y[0].

Za primerjavo še rezultat z lastno implementacijo Runge-Kutta 4. reda:

array([0. , 0.96163898, 1.88557156, 2.77327623, 3.6261735 , 4.44562819, 5.23295161, 5.98940363, 6.71619474, 7.41448797])

Prikažemo rezultat:

<Figure size 640x480 with 1 Axes>

Sistem navadnih diferencialnih enačb

Zgoraj smo si pogledali reševanje začetnega problema ene navadne diferencialne enačbe; sedaj bomo reševanje posplošili na začetni problem za sistem mm navadnih diferencialnih enačb prvega reda.

Takšen sistem zapišemo:

y′=f(t,y),\mathbf{y}'=\mathbf{f}(t, \mathbf{y}),

kjer so podani dodatni (začetni) pogoji:

y(t0)=y0.\mathbf{y}(t_0)=\mathbf{y}_0.

S tt smo označili neodvisno spremenljivko (ni nujno, da je to vedno čas) in f\mathbf{f} vektor desnih strani.

Računamo rešitev sistema mm diferencialnih enačb y′=f(t,y)\mathbf{y}'=\mathbf{f}(t, \mathbf{y}) pri a=t0,t1,…,tn−1=ba=t_0, t_1,\dots,t_{n-1}=b, to je mm funkcijskih vrednosti na vsakem koraku yk(ti)y_k(t_i), k=0,1,…,m−1k=0,1,\dots,m-1 in i=0,1,…,n−1i=0,1,\dots,n-1. Lahko se dokaže, da lahko uporabimo vsako metodo, ki smo jo izpeljali za diferencialne enačbe prvega reda tudi za sistem navadnih diferencialnih enačb prvega reda, če zamenjamo skalarne veličine z ustreznimi vektorskimi.

Numerična implementacija

Metodi Euler in Runge-Kutta četrtega reda potrebujeta zgolj malenkostne popravke (y0 je numerično polje, f vrne seznam vrednosti odvodov):

Numerični zgled

Padanje mase nadgradimo v ravninsko gibanje; velikost sile upora zraka naj bo definirana kot:

∣F(v)∣=c ∣v∣2.|\mathbf{F}(\mathbf{v})|=c\,|\mathbf{v}|^2.

Sila upora zraka deluje v nasprotno stran kot kaže vektor hitrosti. Padanje telesa vezano

Ob pomoči slike, definiramo silo v xx smeri:

Fx=−c (vx2+vy2) cos⁡(α)=−c (vx2+vy2) vxvx2+vy2=−c vx vx2+vy2.F_x=-c\,\left(v_x^2+v_y^2\right)\,\cos(\alpha)=-c\,\left(v_x^2+v_y^2\right)\,\frac{v_x}{\sqrt{v_x^2+v_y^2}}=-c\,v_x\,\sqrt{v_x^2+v_y^2}.

Podobno je sila v yy smeri:

Fy=−c vy vx2+vy2.F_y=-c\,v_y\,\sqrt{v_x^2+v_y^2}.

Glede na drugi Newtonov zakon zapišemo sistem dveh (vezanih) diferencialnih enačb prvega reda:

Fx=m vx′,F_x=m\,v_x',
m g+Fy=m vy′,m\,g+F_y=m\,v_y',

mm je masa, gg gravitacijski pospešek, cc koeficient zračnega upora ter vxv_x in vyv_y hitrost v xx oz yy smeri. Diferencialno enačbo bi želeli rešiti glede na začetni pogoj:

vx(0)=vy(0)=5 m/s.v_x(0)=v_y(0)=5\,\textrm{m/s}.

Definirajmo seznam desnih strani:

Definirajmo začetni pogoj in časovni vektor, kjer nas zanima rezultat:

array([0. , 0.05, 0.1 , 0.15, 0.2 ])

Za primerjavo izračunajmo rešitev s funkcijo runge_kutta_4 ter solve_ivp:

Poglejmo rezultat:

array([[5. , 4.23209907, 3.63858619, 3.16619484, 2.78087608], [5. , 4.68459713, 4.48359747, 4.35932897, 4.28742151]])
array([[5. , 4.23211316, 3.6399137 , 3.16660748, 2.77780226], [5. , 4.68462761, 4.48494405, 4.35999931, 4.28466858]])

Prikažemo rezultat:

<Figure size 640x480 with 1 Axes>

Preoblikovanje diferencialne enačbe višjega reda v sistem diferencialnih enačb prvega reda

Pogledali si bomo, kako navadno diferencialno enačbo poljubnega reda nn:

y(n)=f(t,y,y′,y′′,…,y(n−1)),y^{(n)}=f(t, y, y', y'',\dots,y^{(n-1)}),

pri začetnih pogojih:

y(t0)=k0,y′(t0)=k1,…y(n−1)(t0)=kn−1y(t_0)=k_0,\quad y'(t_0)=k_1,\quad\dots\quad y^{(n-1)}(t_0)=k_{n-1}

preoblikujemo v sistem diferencialnih enačb prvega reda.

Najprej namesto odvodov vpeljemo nove spremenljivke:

yi=y(i),i=0,1,…,n−1.y_i=y^{(i)}, \qquad i=0,1,\dots,n-1.

Diferencialna enačba nn-tega reda zapisana z novimi spremenljivkami je:

yn−1′=f(t,y0,y1,y2,…,yn−1).y_{n-1}'=f(t, y_0, y_1, y_2,\dots,y_{n-1}).

Nove funkcije odvajamo po neodvisni spremenljivki:

yi′=y(i+1)=yi+1,i=0,1,…,n−2y_i'=y^{(i+1)}=y_{i+1}, \qquad i=0,1,\dots,n-2

in

yn−1′=f(t,y0,y1,y2,…,yn−1).y_{n-1}'=f(t, y_0, y_1, y_2,\dots,y_{n-1}).

Dobili smo sistem navadnih diferencialnih enačb prvega reda:

y0′=y1y1′=y2…yn−1′=f(t,y0,y1,y2,…,yn−1)\begin{array}{rcl} y_0'&=&y_1\\ y_1'&=&y_2\\ &\dots\\ y_{n-1}'&=&f(t, y_0, y_1, y_2,\dots,y_{n-1})\\ \end{array}

pri začetnih pogojih:

y0(t0)=k0,y1(t0)=k1,…y(n−1)(t0)=kn−1.y_0(t_0)=k_0,\quad y_1(t_0)=k_1,\quad\dots\quad y_{(n-1)}(t_0)=k_{n-1}.
Numerični zgled

Vrnemo se k padajoči masi: Padanje telesa

Vendar tokrat drugi Newtonov zakon zapišimo glede na pomik (diferencialna enačba drugega reda):

Fx=m x′′,F_x=m\,x'',
m g+Fy=m y′′,m\,g+F_y=m\,y'',

mm je masa, gg gravitacijski pospešek, cc koeficient zračnega upora ter x′′x'' in y′′y'' pospešek v izbranem koordinatnem sistemu. Začetni pogoji:

x(0)=y(0)=0 minx′(0)=y′(0)=5 m/s.x(0)=y(0)=0\,\textrm{m}\qquad\textrm{in}\qquad x'(0)= y'(0)=5\,\textrm{m/s}.

Imamo sistem dveh diferencialnih enačb drugega reda. Z uvedbo novih spremenljivk yiy_i:

y0=x,y1=x′,y2=y,y3=y′.y_0= x,\quad y_1= x',\quad y_2= y,\quad y_3= y'.

Pripravimo sistem diferencialnih enačb prvega reda:

y0′=y1y1′=Fx/my2′=y3y3′=g+Fy/m\begin{array}{rcl} y_0'&=&y_1\\ y_1'&=&F_x/m\\ y_2'&=&y_3\\ y_3'&=&g+F_y/m \end{array}

Definirajmo Pythonovo funkcijo desnih strani / prvih odvodov:

Definirajmo začetni pogoj in časovni vektor, kjer nas zanima rezultat:

array([0. , 0.05, 0.1 , 0.15, 0.2 ])

Izračunamo rešitev:

Poglejmo rezultat ([x,x′,y,y′][x, x', y, y']):

array([[0. , 0.22992477, 0.42611996, 0.59587483, 0.74424286], [5. , 4.23183658, 3.64002431, 3.16703014, 2.77775353], [0. , 0.24153615, 0.47038377, 0.69124852, 0.9072755 ], [5. , 4.68435696, 4.48497294, 4.36034218, 4.28444004]])

Prikažemo rezultate; najprej hitrost, nato lego (yy koordinata je pozitivna navzdol)!

<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>

Stabilnost reševanja diferencialnih enačb*

Numerično reševanje diferencialnih enačb je izpostavljeno napaki metode in zaokrožitveni napaki. Te napake so pri različnih numeričnih metodah različne.

Reševanje diferencialne enačbe je stabilno, če majhna sprememba začetnega pogoja vodi v majhno spremembo izračunane rešitve; sicer govorimo o nestabilnosti reševanja.

Stabilnost je odvisna od diferencialne enačbe, od uporabljene numerične metode in od koraka integracije hh.

Primer preprostega nihala

Poglejmo si najprej primer reševanja diferencialne enačbe preprostega nihala. Slika nihala

Slika (vir: Slavič, Dinamika, mehanska nihanja in mehanika tekočin, 2017) prikazuje dinamski sistem (masa mm, togost kk), katerega diferencialna enačba je

m x′′+k x=0.m\, x'' + k\,x=0.

Tako diferencialno enačbo preoblikujemo v standardno obliko lastnega nihanja:

x′′+ω02 x=0,x'' + \omega_0^2\,x=0,

kjer je lastna krožna frekvenca:

ω0=km\omega_0=\sqrt{\frac{k}{m}}

in pričakujemo odziv oblike:

x(t)=A cos⁡(ω0 t)+B sin⁡(ω0 t).x(t)=A\,\cos(\omega_0\,t)+B\,\sin(\omega_0\,t).

Če so začetni pogoji:

x(0 s)=x0inx′(0 s)=0 m/s,x(0\,\textrm{s})=x_0\qquad\textrm{in}\qquad x'(0\,\textrm{s})=0\,\textrm{m/s},

je rešitev začetnega problema:

x(t)=x0 cos⁡(ω0 t).x(t)=x_0\,\cos(\omega_0\,t).
Numerični zgled

Najprej definirajmo vektor začetnih pogojev in funkcijo desnih strani / prvih odvodov (diferencialno enačbo drugega reda pretvorimo v sistem diferencialnih enačb prvega reda y′=f(t,y)\mathbf{y}'=\mathbf{f}(t, \mathbf{y})), kjer velja y0=x,y1=x′y_0=x, y_1=x':

Definirajmo podatke in analitično rešitev:

Rešitev s pomočjo metod Euler in Runge-Kutta četrtega reda:

Prikažimo rezultate:

<Figure size 640x480 with 1 Axes>

Opazimo, da je Eulerjeva metoda nestabilna in če bi povečali korak, bi postala nestabilna tudi metoda Runge-Kutta četrtega reda.

Zakaj je Eulerjeva metoda tako nestabilna?
array([ 1. , 1. , 0.93683453, 0.8105036 , 0.62499707, 0.3882947 , 0.1121141 , -0.18859332, -0.49638247, -0.79225904])

Spomnimo se Eulerjeve metode:

x(t+h)=x(t)+x′(t) h,x(t+h)=x(t)+x'(t)\,h,

ki nam pove, da pomik x(t+h)x(t+h) določimo glede na lego x(t)x(t) in hitrost x′(t)x'(t). Začetni pogoji izhajajo iz skrajnega odmika x(t=0)=1x(t=0)=1 in takrat je hitrost x′(t=0)=0x'(t=0)=0, kar pomeni, da bo x(t+h)=1x(t+h)=1. Že v prvem koraku torej naredimo razmeroma veliko napako. Vendar zakaj potem začne vrednost alternirajoče naraščati?

Spomnimo se, da je analitična rešitev x(t)=x0 cos⁡(ω0 t)x(t)=x_0\,\cos(\omega_0\,t) in je torej x′(t)=−ω0 x0 sin⁡(ω0 t)x'(t)=-\omega_0\,x_0\,\sin(\omega_0\,t).

Vstavimo pripravljena izraza v Eulerjevo metodo in uredimo:

x(t+h)=x(t)+x′(t) h=x0 (cos⁡(ω0 t)−ω0 h sin⁡(ω0 t)).x(t+h)=x(t)+x'(t)\,h=x_0\,\left(\cos(\omega_0\,t)-\omega_0\,h\,\sin(\omega_0\,t)\right).

Predpostavimo, da gledamo stanje ob takem času t=π/(2ω0)t=\pi/(2\omega_0), ko velja cos⁡(ω0 t)=0\cos(\omega_0\,t)=0 in sin⁡(ω0 t)=1\sin(\omega_0\,t)=1:

x(t+h)=x0 (−ω0 h)⏟A.x(t+h)=x_0\,\underbrace{\left(-\omega_0\,h\right)}_{A}.

V kolikor bo absolutna vrednost izraza AA večja kot 1, bo pri času t+ht+h vrednost večja kot v predhodnem koraku in v sledečem verjetno spet. Sledi, da lahko pride do nestabilnosti. Da se je izognemo, mora veljati:

∣A∣<1→h<1ω0.|A|<1\qquad\rightarrow\qquad h<\frac{1}{\omega_0}.

Opomba: v nekaterih knjigah boste videli tudi vrednost h<2/ω0h<2/\omega_0; enolične meje za vse diferencialne enačbe ni mogoče definirati; v splošnem pa velja, da je korak definiran relativno glede na najkrajšo periodo TT v diferencialni enačbi (npr.: h<2/ω0h<2/\omega_0 je v bistvu enako h<2/(2π/T)h<2/(2\pi/T) oziroma h<T/πh<T/\pi). Perioda TT je definirana glede na najvišjo lastno frekvenco sistema T=1/fmaxT=1/f_{\textrm{max}}, ki jo izračunamo iz lastne vrednosti sistema.

Dodatno: Primer Van der Polovega nihala

Namen tega primera je pokazati, kako lahko izbira integratorja vpliva na hitrost reševanja problema! Van der Polovo nihalo je opisano tukaj.

Definirajmo seznam odvodov:

Rešitev po metodi RK45 (gre za eksplicitno shemo, ki ni primerna za toge sisteme diferencialnih enačb; reševanje je zelo počasno, zato rešitev računamo samo do t1/100):

Implicitna shema BDF (angl. Backward Differentiation Formulas) se tukaj izkaže kot bistveno bolj primerna. Zaradi stabilnosti, so koraki lahko bistveno večji in zato je reševanje bistveno hitrejše:

<Figure size 640x480 with 1 Axes>

Dodatno: simbolno reševanje diferencialne enačbe drugega reda

Pogledali si bomo primer, prikazan na sliki, kjer je masa mm na klancu naklona α\alpha. Koeficient trenja je μ\mu, težnostni pospešek pa gg. Začetna hitrost je y˙(0 s)=v0\dot y(0\,\textrm{s})=v_0, pomik y(0 s)=0 my(0\,\textrm{s})=0\,\textrm{m}. Masa na klancu Gibalna enačba (samo za smer yy) je definirana glede na II. Newtonov zakon (glejte diagram sil na prosto telo).

Izpeljava gibalne enačbe
Loading...

Rešitev enačbe je:

Loading...

Da določimo C1C_1 in C2C_2, vstavimo t=0 st=0\,\textrm{s}:

Loading...

Nato odvajamo po času in ponovno vstavimo t=0 st=0\,\textrm{s}:

Loading...

Glede na začetne pogoje smo torej določili konstante:

Sledi rešitev:

Loading...

Pripravimo si funkciji za numerični klic:

Pomik pri 0s: 0m
Hitrost pri 0s: 1m/s

Pripravimo prikaz:

<Figure size 640x480 with 1 Axes>
Simbolno preoblikovanje diferencialne enačbe v sistem diferencialnih enačb prvega reda

Spomnimo se izvorne diferencialne enačbe:

Loading...

Definirajmo nove spremenljivke in pripravimo funkcijo ff:

Loading...

Povežimo sedaj nove spremenljivke.

dy0/dtd y_0/dt naj bo enako y1y_1:

Loading...

Odvod dy1/dtd y_1/dt (v bistvu je to y′′y'') naj bo enak funkciji ff:

Loading...

Zgornje izraze zapišemo v vektorski obliki:

y′=f(t,y).\mathbf{y}'=\mathbf{f}(t, \mathbf{y}).
Loading...
Loading...

Spomnimo se sedaj f_vec:

Loading...

Če rešujemo numerično, potem funkcijo f(t,y)\mathbf{f}(t, \mathbf{y}) zapišemo:

Loading...

Preverimo funkcijo pri začetnem času t=0 t=0\,s in pri začetnih pogojih [y0,y1]=[0,v0][y_0, y_1]=[0, v_0]:

array([0., 1.])
array([ 1. , -0.30370487])

Uporabimo sedaj Eulerjevo metodo:

array([[ 0. , 1. ], [ 1. , 0.69629513], [ 1.69629513, 0.39259025], [ 2.08888538, 0.08888538], [ 2.17777075, -0.2148195 ]])

Prikažemo in primerjamo z analitično rešitvijo:

Loading...

Vprašanja za vaje


Vprašanje 1: Diferencialno enačbo:

y′−y=sin⁡(x)y' - y = \sin(x)

rešite simbolno z uporabo modula sympy. Prikažite rešitev na intervalu x∈[0,5]x\in [0, 5] (namig: y=y(x)y = y(x)). Vrednosti neznank so pozitivne in realne.

Začetni pogoj: y(x=0)=0y(x = 0) = 0


Eulerjeva metoda

Vprašanje 2: Diferencialno enačbo:

y′−y=sin⁡(x)y' - y = \sin(x)

rešite še numerično s pripravljeno funkcijo Eulerjeve metode za 30 vrednosti na intervalu x∈[0,5]x \in [0, 5].

Začetni pogoj: y(x=0)=0y(x = 0) = 0

Vprašanje 3: Prikažite vrednosti napake numerične rešitve z Eulerjevo metodo, ko število diskretnih točk na intervalu x∈[0,5]x \in [0, 5] povečujete od 10 do 100 s korakom 30.


Reševanje navadnih D. E. višjega reda

Vprašanje 4: Padalec z maso mm je izpostavljen gravitaciji in sili zračnega upora. Gibanje padalca opisuje diferencialna enačba:

y¨=g−CDmy˙2\ddot{y} = g - \frac{C_D}{m}\dot{y}^2

Zapišite sistem diferencialnih enačb prvega reda in pripravite funkcijo za numerično reševanje. Izračunajte vrednosti funkcije prvih odvodov pri začetnem času in začetnih pogojih.

Podatki:

  • g=9.81m/s2g = 9.81 \text{m/s}^2

  • CD=0.203kg/mC_D = 0.203 \text{kg/m}

  • m=80kgm = 80 \text{kg}

  • y(0)=y˙(0)=0y(0) = \dot{y}(0) = 0


Vprašanje 5: Zgoraj pripravljeno funkcijo uporabite pri numeričnem reševanju diferencialne enačbe padalca s funkcijo scipy.integrate.solve_ivp pri 100 diskretnih točkah za prvih 30 sekund padca.

Izrišite dobljen potek poti (yy) in hitrosti padalca v odvisnosti od časa tt. Kako bi izračunali tudi pospešek?

Vprašanje 6: Izstrelek mase mm izstrelimo s hitrostjo v0v_0 pod kotom α\alpha. Gibalni enačbi za pomike v smereh xx in yy sta:

x¨(t)=−F cos(α)my¨(t)=−F  sin(α)m−g\ddot{x}(t) = - F~\frac{\text{cos}(\alpha)}{m} \qquad \ddot{y}(t) = -F~\frac{~\text{sin}(\alpha)}{m} - g

Sila upora FF je enaka F=c v3/2F = c~v^{3/2}, pri čemer je hitrost v=x˙2+y˙2v = \sqrt{\dot{x}^2 + \dot{y}^2} in α=arctan⁡(y˙x˙)\alpha = \arctan{\Big(\frac{\dot{y}}{\dot{x}}\Big)}

vir: Numerical Methods in Engineering With Python 3, 3rd Ed, Jaan Kiusalaas

Sistem dveh diferencialnih enačb drugega reda zapišite v obliki sistema štirih diferencialnih enačb prvega reda in določite vektor začetnih pogojev.

Podatki:

  • α0=π/3 rad\alpha_0 = \pi/3 ~ \text{rad}

  • v0=32 m/sv_0 = 32 ~ \text{m/s}

  • g=9.81 m/s2g = 9.81 ~ \text{m/s}^2

  • c=0.029 kg/(ms2)c = 0.029 ~ \text{kg}/(\text{ms}^2)

  • m=0.41 kgm = 0.41 ~ \text{kg}

Vprašanje 7: Pripravite funkcijo odvodov za numerično reševanje zgornjega sistema dveh diferencialnih enačb 2. reda in z uporabo scipy.integrate.solve_ivp in določite krivuljo leta izstrelka pri 100 diskretnih točkah v času t∈[0,5]t \in [0, 5] s.

x¨(t)=−F cos⁡(α)my¨(t)=−F sin⁡(α)m−g\ddot{x}(t) = - F~\frac{\cos(\alpha)}{m} \qquad \ddot{y}(t) = -F~\frac{\sin(\alpha)}{m} - g

Sila upora FF je enaka F=c v3/2F = c~v^{3/2}, pri čemer je hitrost v=x˙2+y˙2v = \sqrt{\dot{x}^2 + \dot{y}^2} in α=arctan⁡(y˙x˙)\alpha = \arctan{\Big(\frac{\dot{y}}{\dot{x}}\Big)}

Vprašanje 8: Podan sistem dveh diferencialnih enačb drugega reda rešite še s pomočjo funkcije scipy.integrate.solve_ivp z metodo 'LSODA'.

Sistem enačb integrirajte do časa, ko izstrelek pade na tla (y=0y = 0). Uporabite enake začetne pogoje kot pri prejšnji nalogi in maksimalni razmik na časovni osi Δt=0.1\Delta t = 0.1 s.

Grafično prikažite dobljeno trajektorijo leta izstrelka.