2017-06-27 5 views
0

Ok, also versuche ich ein Anfangswertproblem zu lösen, versuche die Geschwindigkeit zu finden, die von der f Funktion mit Runge-Kutta 2 gegeben wird. Mein Programm kompiliert, aber wenn ich es laufe gibt mir den gleichen Wert für v jederzeit, aber ich kann einfach nicht finden, wo ich es falsch mache. Könnte mir jemand helfen?Nur Nullen mein Fortran Runge-Kutta

program runge 
implicit none 

real(8) :: f,t,y,g,v,c1 
real(8) a,b,h 
real(8) k1,k2,l1,l2,v0,gr,m 
integer i,n,j 

n=10 
a=0 
b=100 
h=(b-a)/n 
gr=9.8100 
m=70.0 
c1=15.0 
v0=20.0 
y=0.0 

v=v0 
t=a 

open(1, file="velocidad.txt") 
write(1,*) a,v 
print*, "  t", "  v" 

do i=1,n 

    k1 = f(t,v) 
    k2 = f(t + h, v + h*k1) 
    v = v + h*(k1 + k2)/2 
    t = a + i*h 

    write(1,*) t, v 
    print*, t, v 

end do 
close(1) 

end program runge 

real(8) function f(t,y) 
    implicit none 
    real(8) :: t,y,c1,gr,v,m 

    f = -(gr)-((c1/m)*v) 

end function f 

wenn ich es benutze ich bekommen und Ausgabe wie folgt:

t    v 
10.000000000000000  20.000000000000000 
20.000000000000000  20.000000000000000 
30.000000000000000  20.000000000000000 
40.000000000000000  20.000000000000000 
50.000000000000000  20.000000000000000 
60.000000000000000  20.000000000000000 
70.000000000000000  20.000000000000000 
80.000000000000000  20.000000000000000 
90.000000000000000  20.000000000000000 
100.00000000000000  20.000000000000000 

Antwort

1

denke ich Ihr Problem in Ihrer Funktion liegt f, speziell in dieser Zeile:

f = -(gr)-((c1/m)*v) 

Die Funktion hat ein eigener Bereich, dh keiner der Variablen, denen Sie in Ihrem Hauptprogramm einen Wert zugewiesen haben, kann die Funktion zur Verfügung stehen, stattdessen hat sie eigene Variablen gr , c1 und m. Es werden nur t und y übergeben, aber das Ergebnis der Funktion ist immer noch zu klein, um eine sinnvolle Änderung in v zu registrieren. (Wenn ich Ihren Code ausführen, sind die Ergebnisse von f in der Größenordnung von -2e-314, aber da Sie nie die Variablen innerhalb der Funktion initialisieren, können Sie Ihre Werte unterscheiden.)

Als für das, was Sie tun können:

  1. Verschieben Sie die Initialisierung von gr, c1 und m in die Funktion. Diese Werte scheinen sich nicht zu ändern.

  2. die gesamte Funktion in das Hauptprogramm bewegen, und entfernen Sie die klare Angabe von gr, c1 und m aus der Funktion. Auf diese Weise es für die Variablen in den Eltern Umfang aussehen:

    program runge 
        ... 
        end do 
        close(1) 
    contains 
        real(8) function f(t, y) 
         implicit none 
         real(8) :: t, y 
         f = -(gr)-((c1/m)*v) 
        end function f 
    end program runge 
    

    Hinweis, dass es keine Erklärung von gr ist, c1, m oder v innerhalb der Funktion.

  3. Setzen Sie die Funktion und die Variablen, die es auf in ein Modul abhängt:

    module my_mod 
        implicit none 
        real(8) gr, c1, m, v 
    contains 
        real(8) function f(t, y) 
         ... 
        end function 
    end module 
    
    program runge 
        use my_mod 
        implicit none 
        gr = 9.81 
        ... 
    end program 
    

    Beachten Sie, dass hier gibt es keine Erklärung von gr usw. im Hauptprogramm ist, da diese Variablen vom Modul geliefert werden .

Es gibt viele andere Fragen, hier sind nur ein paar Beispiele:

  • Ihre Funktion Dummy-Variablen hat t und y aber nie wirklich nutzt sie
  • Sie eine Datei auf Gerät öffnen 1, die je nach Compiler möglicherweise andere E/A-Funktionen beeinträchtigen können.Ich verwende nur Einheiten> 10, oder noch besser, eine ganze Zahl für meine Einheit erklären und open(newunit=myunit, file=....) für die offene verwenden, dann lesen und schreiben mit read(myunit, ... und write(myunit, ...
  • Ihre Nutzung von real(8) ist nicht unabhängig Compiler. Besser wäre so etwas wie dieses:

    program runge 
        use iso_fortran_env 
        implicit none 
        real(real64) :: gr 
        ... 
    

Aber das war nicht die Frage hier, also werde ich es weglassen.

+0

In der zu integrierenden Funktion sollte 'v' als 'y' gelesen werden. h. "f = - (gr) - ((c1/m) · y)". 'v' sollte in der Funktion überhaupt nicht referenziert werden. – RussF