www.vorhilfe.de
- Förderverein -
Der Förderverein.

Gemeinnütziger Verein zur Finanzierung des Projekts Vorhilfe.de.
Hallo Gast!einloggen | registrieren ]
Startseite · Mitglieder · Impressum
Forenbaum
^ Forenbaum
Status VH e.V.
  Status Vereinsforum

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Suchen
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Weitere Fächer:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
Forum "Uni-Numerik" - Runge-Kutta-Verfahren in C++
Runge-Kutta-Verfahren in C++ < Numerik < Hochschule < Mathe < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "Uni-Numerik"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

Runge-Kutta-Verfahren in C++: Tipp
Status: (Frage) beantwortet Status 
Datum: 20:28 Do 29.01.2015
Autor: binhbob

Aufgabe
Runge-Kutta-Verfahren in C++ implementieren.


Hallo, ich wollte das Runge-Kutta-Verfahren zur Lösung der Bewegungsdgl. in C++ implementieren.

Bewegungsdgl.: m*y''+d*y'+k*y = p

Umformung in eine DGL-System erster Ordnung.

y  = y0
y' = y1
y''= -(d/m)*y1-(k/m)*y0+p/m

Dabei ist der nächste Schritt   [mm] y_m+1 [/mm] = [mm] y_m [/mm] +h*y'_m

// c++ Code

//Startwerte

    x.at(0)=x0;    //x=y0            
    v.at(0)=v0;    //v=y1
    a.at(0)=-(d/m)*v.at(0)-(k/m)*x.at(0)+(p/m);  //a=y''

// kann man den Startwert von a so berechnen?

for(unsigned int i=1; i<(n); i++)
{
    xa.at(i)=(h/2.0)*v.at(i-1);  // Koeffizieten für Runge-Kutta
    xb.at(i)=(h/2.0)*xa.at(i);
    xc.at(i)=(h)*xb.at(i);

    x.at(i)=x.at(i-1)+((h/6.0)*(v.at(i-1)+2.0*xa.at(i)+2.0*xb.at(i)+xc.at(i)));

    va.at(i)=(h/2.0)*a.at(i-1);  // Koeffizieten für Runge-Kutta
    vb.at(i)=(h/2.0)*va.at(i);
    vc.at(i)=(h)*vb.at(i);

    v.at(i)=v.at(i-1)+((h/6.0)*(a.at(i-1)+2.0*va.at(i)+2.0*vb.at(i)+vc.at(i)));

    a.at(i)=-(d/m)*v.at(i)-(k/m)*x.at(i)+(p/m);  // Hier ist der Knackpunkt. Kann ich a so direkt berechnen? Oder muss ich auf a das Runge-Kutta-Verfahren anwenden. So komme ich theoretisch auf den nächsten Schritt von a.

}

Das Programm läuft. Jedoch liefert die numerische Lösung nicht annähernd die analytische Lösung.
Die Probleme:
1.) Die Frequenz der Schwingung ist zu niedrig um genau zu sein ungefähr um den Faktor 6.
2.) Die Amplitude nimmt zu, wenn die Dämpfung(d) gleich Null ist. Jedoch stimmt die Amplitude der Schwigung.


Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.

        
Bezug
Runge-Kutta-Verfahren in C++: Antwort
Status: (Antwort) fertig Status 
Datum: 12:07 Fr 30.01.2015
Autor: leduart

Hallo
irgendwas ist falsch an deinen Fprmeln
was di am Anfang darüber schreibst ist falsch das ist das einfache Eulerverfahren.
schreib bitte die Runge Kutta Formel hin, die du verwenden willst.
Sicher falsch ist, dass du  zu oft mit h multiplizierst
deine  Koeffizienten mit h und dann am Ende nochmal mit h/6 [mm] x_b [/mm] hat schon [mm] h^2 [/mm] am Ende dann [mm] h^3! [/mm]
Vielleicht solltest du um nicht durcheinander zu kommen die Koeffizienten und die x mit verschiedenen Namen belegen
Gruß leduart
  

Bezug
                
Bezug
Runge-Kutta-Verfahren in C++: Frage (beantwortet)
Status: (Frage) beantwortet Status 
Datum: 18:41 Fr 30.01.2015
Autor: binhbob

Also das Runge-Kutta-Verfahren, dass ich verwenden will ist das klassische Runge-Kutta-Verfahren vierter Ordnung.

Also es stimmt wenn man es genau nimmt ist es $ [mm] y_m+1=ym+h/6\cdot{}(k1+2k2+2k2+k4) [/mm] $

Ich habe grad rübergeguckt und der Algorithmus stimmt einfach nicht..
Dieser Algorithmus hier klappt aufjedenfall für diese Funktion y'=y

k1[i] := y[i-1];
k2[i] := y[i-1]+(1/2)*h*k1[i];
k3[i] := y[i-1]+(1/2)*h*k2[i];
k4[i] := h*k3[i]+y0[i-1];
y[i] := y[i-1]+(1/6)*h*(k1[i]+2*k2[i]+2*k3[i]+k4[i])

Dieser wurde in Maple geschrieben und liefert auch genau die E-Funktion.

Nur wie verknüpfe ich mein Gleichungssystem erster Ordnung miteinander?

Wenn ich jetzt diesen Algorithmus auf meine beiden ersten DGL anwende
(y  = y0; y' = y1), dann kriege ich ja für beide Funktion eine E-Funktion? Doch die sollen ja schwingen.


Ich habe dabei noch eine anderen Annahme wir wollen ja den nächsten Schritt berechnen und nähern uns diesen so, indem wir unseren derzeitigen Funktionswert $ [mm] y_m [/mm] $ + der Schrittweite h * der Ableitung $ [mm] y_m' [/mm] $ an der Stelle. Da wir ja unsere Ableitung kennen.
x'=v könnte man doch schlicht für die Ableitung v einsetzen.
So wäre der nächste Schritt $ [mm] y_m+1=y_m+h\cdot{}v_m [/mm] $ oder?

Bezug
                        
Bezug
Runge-Kutta-Verfahren in C++: Antwort
Status: (Antwort) fertig Status 
Datum: 22:12 Fr 30.01.2015
Autor: leduart

Hallo
Du hast anscheinend das Runge Kutta verfahren nicht verstanden
was du vorschlägst ist das einfache Eulerverfahren, das aber schnell versagt, probier es mal mit y'=-y  y(0=1 sollte den cos liefern aus (auch dein eigenartiges Verfahren, mit deinen k, warum das funktioniert verstehe ich nicht, es kann hüchstens für diese einfachste Dgl funktionieren, du hast in [mm] k_1 [/mm] ja einfach, wenn du die Endformel ansiehst h!6*y(i-1) addiert. mit 2*k2 gehst du dann nochmal 2h/6* (y(i-1) und [mm] h^2/6 [/mm]
mit [mm] k_3 [/mm] hast du h^63 erreich mit [mm] k_4 [/mm] dann [mm] h^4 [/mm]  wenn h klein genug ist fällt das wwohl wef.
schreib mal deine k so um, dass du sie nicht ineinander einsetzt, sondern wirklich einsetzt. dann sieht das gräßlich aus. kriegst du wirklich in maple damit DIE e funktion, oder einfach eine so ähnliche? wenn die [mm] h^2 [/mm] klein genug sind spielen sie kaum eine Rolle gegen h und du hast insgesamt auf raffinierte und umständliche Weise  einfach yI)=y(i-1)+h*y(i-1) wobei ja y(i-1) auch y'(i-1)ist, also ein Verfahren, das genau deine und nur dein y'=y  halbwegs lost.  rechne mal mit berschiedenen h y(1) aus, das sollt e ergeben!
jetzt zum richtigen RK
was heisst Ich habe grad rübergeguckt und der Algorithmus stimmt einfach nicht.
worüber? über deinen code oder das richtige Verfahren? das richtige stimmt und wird unglaublich oft benutzt
musst du Runge Kutta? für dgl 2 ter ordnung reicht auch das "Halbschrittverfahren:"
Dgl: y'=f(y) (auch f(t,y) y,f skalar oder Vektoren.
du hast [mm] y_0 [/mm] daraus [mm] y_m=y_0+h/2*F(y) [/mm] d.as heisst du rechnest den Wert nach einem halben Schritt aus indem du mit der Steigung y' das Stück h/2 weiter gehst. mit der Steigung in der Mitte gehst du jetzt vom Anfangspunkt an einen ganzen Schritt weiter. dann hast du [mm] y_1=y_0+h*F(y_m) [/mm]
beim Runge Kutte rechnet man jetzt die Steigung nicht nur in der Mitte aus, sondern an 3 Zwischenstellen, diese  mittelt man gewichtet.
also [mm] y_{m1}=y_0+h/2*F(y_0) [/mm]
[mm] y_{m2}=y_0+h/2*F(y_(m1) [/mm]
[mm] y_(m3)=y_o+h*F(y_{m2} [/mm]
diese 4 Steigungen mittelt man jetzt mit den Gewichten 1,2,2,1
und hat dann [mm] y_1=y_0+h/6*(F((y_{0}+2*F(y:{m1}+2*F(y_{m2}+1*F(y(m_3)) [/mm]
das sollten deine [mm] k_i [/mm] sein Die [mm] k_i [/mm] sind also nichts anderes als Steigungen an den Zwischenstellen.
wird es damit klarer.
du hast eine Vektorfkt
mit deinen Namen [mm] \vektor{x \\ v}'=(\vektor{v\\ f(x,v} [/mm] dein f ist das was du a genannt hast
und musst natürlich immer beide Komponenten parallel rechnen um f an den entsprechenden Stellen zu kennen.
Gruß leduart



Bezug
        
Bezug
Runge-Kutta-Verfahren in C++: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 18:40 Fr 30.01.2015
Autor: binhbob

Also das Runge-Kutta-Verfahren, dass ich verwenden will ist das klassische Runge-Kutta-Verfahren vierter Ordnung.

Also es stimmt wenn man es genau nimmt ist es [mm] y_m+1=ym+h/6*(k1+2k2+2k2+k4) [/mm]

Ich habe grad rübergeguckt und der Algorithmus stimmt einfach nicht..
Dieser Algorithmus hier klappt aufjedenfall für diese Funktion y'=y

k1[i] := y[i-1];
k2[i] := y[i-1]+(1/2)*h*k1[i];
k3[i] := y[i-1]+(1/2)*h*k2[i];
k4[i] := h*k3[i]+y0[i-1];
y[i] := y[i-1]+(1/6)*h*(k1[i]+2*k2[i]+2*k3[i]+k4[i])

Dieser wurde in Maple geschrieben und liefert auch genau die E-Funktion.

Nur wie verknüpfe ich mein Gleichungssystem erster Ordnung miteinander?

Wenn ich jetzt diesen Algorithmus auf meine beiden ersten DGL anwende
(y  = y0; y' = y1), dann kriege ich ja für beide Funktion eine E-Funktion? Doch die sollen ja schwingen.


Ich habe dabei noch eine anderen Annahme wir wollen ja den nächsten Schritt berechnen und nähern uns diesen so, indem wir unseren derzeitigen Funktionswert [mm] y_m [/mm] + der Schrittweite h * der Ableitung [mm] y_m' [/mm] an der Stelle. Da wir ja unsere Ableitung kennen.
x'=v könnte man doch schlicht für die Ableitung v einsetzen.
So wäre der nächste Schritt [mm] y_m+1=y_m+h*v_m [/mm] oder?



Bezug
Ansicht: [ geschachtelt ] | ^ Forum "Uni-Numerik"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
ev.vorhilfe.de
[ Startseite | Mitglieder | Impressum ]