Fallunterscheidung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Hi Leute ich habe einen Fehler im denken, komme mit meiner Schleife nicht weiter...Der Ball wird durch die Gravitationskraft runtergezogen und ab da wo das wasser animiert ist greift die auftriebskraft ein so dass der ball wieder hochgedrückt wird, hier ist jedoch der Fehler , die kräfte werden nicht mehr beim austreten des Wassers subtrahiert und der Ball fliegt weiterhin hoch da sich die hohen Auftriebskrfte nicht mehr wegadieren.
Mein Fehler wird wohl die Unkenntnis darüber sein , wie man die schleife so verschachtelt dass die dritte if abfrage auch bei höher y 0.45 ist + es soll im gegnsatz zu der ersten if abfrage nicht nur die Gravitationskraft drinne ist sondern die Auftriebskraft raussubtrahiert werden soll, damit der ball nich ohne ende hoch fliegt.

Ich schicke nur die Schleife , dass problem sollte nur in dieser sein.

Code: Alles auswählen

for k in np.arange(npts-1): 
    global y
    if y[k+1] >=0.45:
        v[k+1] = v[k]+dt*F_Gr
        y[k+1] = y[k] + v[k] * dt                                                   #y ist der aktuelle punkt des balls
    elif y[k+1] <= 0.45:                                                              #Hier tritt der Ball ins wasser ein            
        h[k+1] = h[k]+0.045-y[k]                                                 #Höhe Kugeltiefe
        Vr[k+1]=(np.pi/3)*(h[k]**2)*(3*r-h[k])                          #Volumen kugel
        FA[k+1] = FA[k]+p_wasser*Vr[k]*g*0.000005             #p_wasser*A*g = FA = Auftriebskraft
        FR = 6*np.pi*0.05*v[k]*vsk_Wasser                             #6pi*0.05*vk = FR = Reibungskraft
        F_Ges[k+1] = F_Gr-(FA[k]+FR)                                       #GesamtKraft F_Gr ist negtiv
        v[k+1] = v[k]+dt+F_Ges[k]
        y[k+1] = y[k] + v[k] * dt
vielen dank schonmal
Thants
User
Beiträge: 34
Registriert: Dienstag 1. Dezember 2020, 12:00

Ich nehme an, die Arrays sollen den zeitlichen Verlauf der Werte speichern, richtig?

Was ist denn der Wert von y[k+1] am Anfang einer Iteration (also beim ersten if)?

Es würde sich hier anbieten, das Programm so zu strukturieren, dass du zuerst die momentan wirkenden Kräfte berechnest und dann daraus die neue Position und Geschwindigkeit bestimmst (vermeiden von doppeltem Code verringert Bugs aufgrund von Tippfehlern wie z.B. aus Versehen ein + anstatt eines * zu setzen ;) ).

(das elif kannst du übrigens durch ein else ersetzen. Der Gleichheitsfall tritt ja nie auf, da bei Gleichheit der erste Block ausgeführt wird und was bleibt ist ja gerade das Gegenteil des ersten if)
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Danke für die Antwort, also der erste wert von y[k+1] ist bei ( 0,0.95) also der ball ist weit oben am rand der achse, es ist übrigens ein 1 dimensionales problem.
und du meinst man sollte in der Schleife die Kräfte ganz am Anfang berechnen weil es sonst Probleme in der Berechnung gibt ? Mir fehlt wohl das grundverständns in welcher Reihenfolge das Programm den code liest ^^..das it dem else stimmt wohl, wobei es drei fallunterscheidungen gibt , deswegen bräucht ich wohl doch ein elif.
Die drei fallunterscheidungen sind fall in der luft, tauchphase und eine phase wo der ball nicht ganz unter wasser ist .(In der Tauchphase wirkt die gravitation nicht mehr und in der fallphase wirkt nur die gravitation ).
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Die Kärfte am anfang der schleife und überhalb der schleife funktioniert nicht , da die range k (sich ändernde werte wie auftriebskraft) in der schleife sein muss.:(
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Wußte noch gar nicht, dass unter Wasser gar keine Gravitation wirkt.
Der Trick besteht darin, gar keine Fallunterscheidung zu haben. Es wirkt immer die Gravitation und für den Teil der unter Wasser liegt (kann auch 0 sein), die Auftriebskraft.
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Ja sie wirkt wohl ...kla ,jedoch wird sie durch die hohe auftriebskraft "neutralisiert"^^,
das komische ist in der elif y[k+1] <=0.45 Bedingung soll erst die höhe berechnet werden (Wie tief der Ball im wasser ist) wenn der ball halt unter 0.45 ist.
Jedoch zeigt mir das h array schon am anfang werte an und somit wird direkt auch ne Auftriebskraft berechnet obwohl der Ball über 0.45 ist....das wundert mich sehr..die bedingung ist ja klar definiert. > erst das h berechnen sobald ball unter 0.45 :(
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Für h wurde vorher ein array mit 300 nullwerten erstellt und als ersten wert eine 0 reingeschrieben...sollte doch eigendlich passen -.-
Thants
User
Beiträge: 34
Registriert: Dienstag 1. Dezember 2020, 12:00

bremen_hs_1992 hat geschrieben: Sonntag 13. Dezember 2020, 16:17 also der erste wert von y[k+1] ist bei ( 0,0.95)
Mehrere Punkte hierzu:
  1. Beachte, die Frage war, was y[k+1] ist, nicht y[0]. Deine Antwort ist (0, 0.95), also ein konstanter Wert, der gar nicht von k abhängt. Dieser Wert wird mit einer weiteren Konstante (0.45) verglichen, d.h. das Ergebnis wäre immer das gleiche und du könntest dir das "if" komplett sparen. Das ist ja aber wohl nicht das, was du eigentlich haben möchtest.
  2. Du sagst, y[k+1] ist (0, 0.95), also praktisch ein 2D-Vektor, vergleichst das aber mit einer einzelnen Zahl. Ist (0, 0.95) größer oder kleiner als 0.45? (wenn y[k+1] tatsächlich zwei Komponenten hätte, hättest du eigentlich beim Ausführen des Programms einen Fehler bekommen müssen)
  3. Auf was ich eigentlich hinaus wollte: Deine if-Bedingung testet den Wert y[k+1], um zu entscheiden, wie es im Programm weiter geht, aber innerhalb der if-Blöcke wird die neue Position berechnet und in genau diesem y[k+1] gespeichert. Das heißt, y[k+1] erhält erst hier seinen Wert und demnach kann der Wert innerhalb der if-Bedingung ja offensichtlich nicht die aktuelle Position des Balls sein.
Zur Umstrukturierung: Wenn du dir dein Programm genau anschaust, stellst du fest, dass beide Zweige am Ende praktisch die gleichen Zeilen haben (Berechnung von v[k+1] und y[k+1]), wobei du im zweiten Zweig "dt+F_Ges[k]" stehen hast, was eigentlich "dt*F_Ges[k]" heissen sollte. Du könntest also die Geschwindigkeits- und Positionsberechnung aus dem if herausziehen und bräuchtest diesen Teil dann nur ein einziges mal. Der Teil mit dem if würde dann nur noch die resultierende Kraft (bzw. Beschleunigung) berechnen.

Zum elif: Klar, wenn du 3 Bedingungen hast, wird auch ein elif mit dabei sein. In dem Programmteil, den du uns gezeigt hast gab es aber nur 2 Fälle. Übrigens, da du ja den Wert 0.45 mehrfach verwendest, wäre es geschickt, eine neue Variable (genau genommen Konstante) einzuführen, meinetwegen mit dem Namen "wasserstand" und dann immer diese zu verwenden. Das hätte zum einen den Vorteil, dass du die Wasserhöhe leicht ändern kannst, ohne dass du in deinem Programm überall nach dem Wert suchen musst (der Wasserstand könnte sich dann auch mit der Zeit ändern) und das Programm ist leichter zu lesen, da durch den Namen bereits die physikalische Bedeutung des Werts sichtbar wird.

Zur Gravitation: Auf der Erdoberfläche wirkt die Gravitation immer und ist in deinem Fall nicht vernachlässigbar. Wenn mehrere Kräfte wirken, kann die resultierende Kraft zwar so sein, dass der Ball stehen bleibt oder sich sogar nach oben bewegt, d.h. aber nicht, dass die Gravitation dann vernachlässigbar ist, es hat sich dann eben ein Kräftegleichgewicht oder auch Ungleichgewicht in die andere Richtung gebildet. Wenn du die Gravitation abschaltest, sobald der Ball das Wasser berührt, würde der Ball ja am Ende auf dem Wasser liegen bleiben und gar nicht ins Wasser eintauchen.
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Danke für deine ausführliche Antwort :)
Zunächst einmal y[k+1] ist der der aktuelle mittelpunkt des balls.
Die (0,0.95) habe ich als Koordinate nur zum Verständniss angegeben , der Ball wird jedoch lediglich mit einem y wert in meinem Code angegeben da es ein eindimensionales Problem ist.
Dein tipp mit y[k+1] nicht in die if bedingungen sondern dort nur die Kärfte zu berechnen werde ich ausprobieren .:)
Mit der Gravitation unter Wasser hast du natürlich recht, muss mich falsch ausgedrückt haben.
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Code: Alles auswählen

for k in np.arange(npts-1): 
    if y[k+1] <= hball:                                                           #Ball tritt grade ins wasser ein (hball ist die postions wo der Ball das Wasser berührt)
        h = hball-y[k]         
        Vr[k+1]=(np.pi/3)*(h**2)*(3*r-h)
        FR[k+1] =6*np.pi*0.05*v[k]*vsk_Wasser               #FR = Reibungskraft
        FA[k+1] = p_wasser*Vr[k]*F_Gr                               #FA = Auftriebskraft
        F_Ges[k+1] = F_Gr + FR[k] + FA[k]
        
    elif y[k+1] <= 0.35:                                                        #Ball ist komplett unter Wasser
        Vr[k+1]= (4/3)*np.pi*r**3                                        #Volumen des Kompletten Balls
        FR[k+1] =6*np.pi*0.05*v[k]*vsk_Wasser               #FR = Reibungskraft
        FA[k+1] = p_wasser*Vr[k]*F_Gr                               #FA = Auftriebskraft
        F_Ges[k+1] = F_Gr + FR[k] + FA[k]                           #Gesamtkraft
    
    else:                                                                                 #Ball oberhalb des Wassers
        F_Ges[k] = F_Gr
    v[k+1] = v[k] + dt*(F_Ges[k]/m)                                   #Bewegungsgleichung
    y[k+1] = y[k] + v[k]*dt                                                    #Positionsgleichung des Balls ( dieser wert wird animiert) 


Hier ist mal meine aktuelle schleife, von meiner sicht müsste es so laufen, jedoch wird der y wert wenn man den ausgibt zu schnell ins unendliche hoch.Die animation spinnt dann natürlich auch.
hat jemand eine idee wo der Dreher sein könnte ?
Vielen dank schonmal
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Da stimmt was mit den Indizes [k] und [k+1] nicht. Da wird was verwendet, was noch gar nicht definiert ist. Die Formel für die Reibungskraft ist falsch, was aber nur einen kleinen Effekt haben dürfte.
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Ich glaube nicht dass es ein Fehler ist mit k und k+1 weil kein Fehler angezeigt wird und er die Berechnungen durchführt
Habe das Gefühl da ist ein dreher in der logik:(
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Da wird natürlich auch kein Fehler angezeigt, weil die Arrays ja schon existieren, aber eben unsinnige Werte enthalten.
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

Hättest du vielleicht einen konkreten gedanken was da schief läuft ? bin am verzweifeln aufgrund der unendlichen suche -.-
schicke hier eben den kompletten code rein , eventuell hilft das mehr

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML
import matplotlib.patches as patches
%matplotlib inline


t_max = 10                                 # Zeitfenster für die Animation in s
v_0 = 0                                    # Anfangsgeschw. in LE/s
y_0 = 0.9                                 # Angangsposition in LE 
frame_rate = 30                            # Anzahl der Frames pro s
dt = 1. / frame_rate                       # Zeitdelay zwischen 2 Frames in sec
t = np.arange(0, t_max, dt)
npts = len(t)

m= 0.05            # vorgegebene Masse aus Aufgabenstellung
g= -0.00001          # negativ da Beschleunigung nach unten
p_wasser = 997      # Dichte Wasser 997KG/m^3  
r = 0.05           #Radius des Kreises
vsk_Wasser = 1         #Viskusität Wasser
F_Gr=m*g
grenze_ball_wasser = 0.45       #Höhe des Balls wo dieser genau am Wasser grenzt


v = np.zeros(npts)  # 300 x 1 Matrix da nur eine eindimensionale Bewegung vorliegt
v[0] = v_0          # Anfangsgeschwindingkeit
y = np.zeros(npts)  # y Vektor für den Ort, bzw Höhe
y[0] = y_0          # Anfangshöhe

h = np.zeros(npts)
h[0] = 0

Vr = np.zeros(npts)
Vr[0] = 0

FA = np.zeros(npts)
FA[0] = 0

FR = np.zeros(npts)
FR[0] = 0

F_Ges = np.zeros(npts)
F_Ges[0] = 0


for k in np.arange(npts-1):
    if y[k+1] <= grenze_ball_wasser:                     #Ball tritt grade ins wasser ein
        h[k+1] = grenze_ball_wasser-y[k]                   #tiefe des balls im wasser
        Vr[k+1]=(np.pi/3)*(h[k]**2)*(3*r-h[k])
        FR[k+1] =6*np.pi*0.05*v[k]*vsk_Wasser               #FR = Reibungskraft
        FA[k+1] = p_wasser*Vr[k]*F_Gr                 #Auftriebskraft
        F_Ges[k+1] = F_Gr + FR[k] + FA[k]
     
    elif y[k+1] <= grenze_ball_wasser-(2*r):            #Ball taucht komplett unters wasser
        Vr[k+1]= (4/3)*np.pi*r**3                    #Volumen Kugel
        FR[k+1] =6*np.pi*0.05*v[k]*vsk_Wasser               #FR = Reibungskraft
        FA[k+1] = p_wasser*Vr[k]*F_Gr                      #Auftriebskraft
        F_Ges[k+1] = F_Gr + FR[k] + FA[k]           

    else:                           #Ball ist ausserhalb des wassers
        F_Ges[k] = F_Gr
    v[k+1] = v[k] + dt*(F_Ges[k]/m)       #bewegungsgleichung
    y[k+1] = y[k] + v[k]*dt               #positionsgleichung
    
    

def animate(k, y):
    x, z = patch.center
    x = 0.5 #5 + 3 * np.sin(np.radians(k))
    z = y[k]
    patch.center = (x, z)
    return patch,





fig = plt.figure(figsize=(5,5))
#fig.set_dpi(100)
#fig.set_size_inches(7, 6.5)

ax = plt.axes(xlim=(0, 1), ylim=(0, 1))
patch = plt.Circle((5, -5), 0.05, fc='r')
rect = patches.Rectangle((0.2,0),0.6,0.4,linewidth=1,edgecolor='r',facecolor='b')
ax.add_patch(rect)


plt.grid()
def init():
    patch.center = (0.5, 0.9)
    ax.add_patch(patch)
    return patch,


anim = animation.FuncAnimation(fig, func = animate, 
                               init_func=init, fargs = (y,),
                               frames=npts, 
                               interval=1./frame_rate*1000.,
                               blit=True,repeat=False)




HTML(anim.to_html5_video())

wenn ich mir dann die aktuellen positionswerte und die animation des balls ansehe fällt mir nix mehr zu ein.

hier zb y:

9.00000000e-001, 9.00000000e-001, 9.00000000e-001,
8.99999989e-001, 8.99999967e-001, 8.99999933e-001,
8.99998472e-001, 8.99995577e-001, 8.99991240e-001,
8.99984565e-001, 8.99974649e-001, 8.99960588e-001,
8.99940912e-001, 8.99913586e-001, 8.99876004e-001,
8.99824640e-001, 8.99754685e-001, 8.99659697e-001,
8.99531015e-001, 8.99356960e-001, 8.99121802e-001,
8.98804372e-001, 8.98376161e-001, 8.97798778e-001,
8.97020532e-001, 8.95971818e-001, 8.94558911e-001,
8.92655607e-001, 8.90091970e-001, 8.86639175e-001,
8.81989104e-001, 8.75726867e-001, 8.67293800e-001,
8.55937649e-001, 8.40645481e-001, 8.20053353e-001,
7.92324674e-001, 7.54986420e-001, 7.04708594e-001,
6.37007251e-001, 5.45844623e-001, 4.23090668e-001,
2.57798024e-001, 3.52257099e-002, -2.64475505e-001,
-6.68033298e-001, -1.21143744e+000, -1.94314942e+000,
-2.92842423e+000, -4.25512942e+000, -6.04157947e+000,
-8.44708191e+000, -1.16861294e+001, -1.60474876e+001,
-2.19198401e+001, -2.98261763e+001, -4.04697345e+001,
-5.47949684e+001, -7.40674202e+001, -9.99758030e+001,
-1.34756008e+002, -1.81325100e+002, -2.43380982e+002,
-3.25339265e+002, -4.31767285e+002, -5.65454274e+002,
-7.21996238e+002, -8.75790198e+002, -9.45515856e+002,
-7.12648480e+002, 3.59934491e+002, 3.49052530e+003,
1.11407151e+004, 2.72680950e+004, 5.51808392e+004,
9.21060409e+004, 1.38625232e+005, -2.90496195e+005,
-1.67352839e+007, -2.68345011e+008, -2.46933605e+009,
-1.37450783e+010, -5.60821768e+010, 1.84581309e+011,
5.43730742e+016, 2.24270670e+020, 1.75119910e+023,
3.04747285e+025, 2.10701110e+027, -6.87695575e+028,
-1.86480288e+045, -1.30857526e+056, -6.22999711e+064,
-3.28322743e+071, -1.08513648e+077, 3.77263660e+081,
7.52280944e+130, 2.59942556e+163, 2.80507710e+189,
4.10567123e+209, 1.48229404e+226, -6.22896928e+239,
-inf, -inf, -inf,
-inf, -inf, nan,
nan, nan, nan,
bremen_hs_1992
User
Beiträge: 23
Registriert: Montag 16. November 2020, 15:11

die gravitation müsste natürlich -9.81 sein , habe da nur rumprobiert
Thants
User
Beiträge: 34
Registriert: Dienstag 1. Dezember 2020, 12:00

Mal zunächst noch was generelles, falls du mit einer Umgebung arbeitest, die einen Debugger enthält, würde ich empfehlen, den Umgang mit diesem zu erlernen. Du könntest dann praktisch Hand--in-Hand mit Python schrittweise durch das Programm laufen und würdest so sehen, welche Programmteile wann ausgeführt werden und welche Werte die einzelnen Variablen haben. Falls kein Debugger zur Hand ist, kann man natürlich auch einfach print-Ausgaben hinzufügen und dann anhand der Ausgabe den Programmablauf verfolgen (ist halt nicht so komfortabel wie ein echter Debugger).

Solange ein Programm noch nicht so läuft wie gewünscht, musst du jede Zeile infrage stellen und nochmal überprüfen, ob die Zeile wirklich das tut, was sie soll. Aber falls es dich tröstet, ich bin davon überzeugt, dass es niemanden gibt, der eine Physik-Simulation implementiert hat und dem die Simulation nicht irgendwann mal um die Ohren geflogen ist, also insofern läuft deine Simulation in völlig normalen Bahnen. :mrgreen:

Zurück zum Programm. Jetzt, wo wir nicht mehr raten müssen, wie deine Werte initialisiert werden, komme ich nochmal zurück zu meiner Frage vom Anfang, was ist der Wert von y[k+1] zu Beginn einer Iteration? Zuletzt sagtest du, es sei der aktuelle Mittelpunkt des Balls. Das reicht mir als Antwort nicht, ich möchte noch die Begründung (praktisch den Beweis) haben, dass es auch tatsächlich so ist. Zeig mir für die ersten drei Iterationen (also für k=0, k=1 und k=2), wo der Wert von y[k+1] geschrieben wurde, der dann von dem ersten if wieder gelesen wird, also von dieser Zeile:

Code: Alles auswählen

    if y[k+1] <= grenze_ball_wasser: 
Also welche Zeile (oder auch Zeilen) haben die drei Werte geschrieben und was waren die Werte?
Antworten