Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws2223:projekt_temperaturveraenderung

Der Einfluss der Temperatur auf die Brownsche Bewegung

-Erarbeitung einer Python-Simulation in Anlehnung an Max Seddigs Forschung-

Gruppenmitglieder: Jasper Mittag, Maxine Krause, Max Liebscher

TO DO:
-Fokus auf Seddigs Temperatur-Auseinandersetzung
-Ausgestaltung des Programms? Wärmestrahlung?
-Code-Ausschnitte? Gesamter Code!!
-Fazit
-Abstimmung zusammengetragener Textabschnitte aufeinander

Einleitung

Die Beschäftigung mit einigen historischen Texten zur Brownschen Bewegung in Vorbereitung auf die Projektphase rückte die Bedeutung der Temperatur in unseren Fokus. Insbesondere in Hinblick auf die kinetische Gastheorie, deren Validierung ein zentrales Thema in der Beschäftigung mit der auch als „Wärmebewegung“ bezeichneten Brownschen Bewegung für die zu Beginn des 20.Jahrhunderts Forschenden darstellte, wurde deutlich: War die zufällige Bewegung der Teilchen Ursache der noch nicht anerkannten kinetischen Theorie der Wärme und ihres Molekül- und Atom-Begriffs, so würde sie auch den Beweis dieser darstellen können.

In unserem Projekt haben wir uns mit dem Einfluss der Temperatur auf die Brownsche Bewegung beschäftigt und das Ganze in Python simuliert. Unser Ziel war es den Einfluss auf die Teilchengeschwindigkeit durch die Veränderung der Temperatur zu zeigen. Wir haben zunächst ein Teilchenbad erschaffen, wo die Teilchen an den Wänden und gegenseitig an anderen Teilchen abstoßen. Anfangs haben wir das mit Turtle simuliert und sind dann später zu Pygame übergegangen.

Anfangs wollten wir die Temperatur als konstanten Faktor einbauen, und daraus immer die Geschwindigkeit berechnen, wir sind aber in der Projektphase zu dem Schluss gekommen, dass es besser wäre die Geschwindigkeit durch eine Art Heizdraht zu beeinflussen, sprich dass von einer Wand für eine gewisse Zeit zusätzliche „Wärmeenergie“ in das Teilchenbad gegeben wird, wodurch die Teilchen, die mit der Wand stoßen schneller werden. Eine Idee war anfangs auch die Temperaturänderung durch einen Slider zu regeln, was wir aber aufgrund mangelnder Zeit nicht geschafft haben einzubauen.

Historische Betrachtung der Forschung Max Seddigs

1904 widmete Max Seddig sich, auf der Suche nach einem experimentellen Beweis der kinetischen Wärmetheorie, erstmals der Abhängigkeit von Teilchenbewegung und absoluter Temperatur. Bis diese 1907 zu einem Abschluss kommen sollten, hatte Einstein als Ergebnis seiner theoretischen Auseinandersetzung die Proportionalität zwischen Start- und Zielpunkt einer Teilchenbewegung und der Wurzel aus Temperatur / Reibungskoeffizient der Flüssigkeit hervorgebracht, die Seddig schließlich experimentell nachzuweisen versuchte.

Zum Ziel führte Seddig in seinen Versuchen ein mit einem „mikrophotographischen Apparat“ verbundenes Ultramikroskop, in das durch eine automatische Belichtungsvorrichtung im Abstand von 1/10 Sekunde zwei 1/40 Sekunde andauernde Lichtblitze die zweifache Abbildungen eines Teilchens, vor und nach zurücklegen einer zu untersuchenden Strecke bei bestimmter Temperatur in genanntem festen Zeitintervall ermöglichte. Grund für die zwei Einzelbelichtungen anstelle der Belichtung des gesamten Weges, den das Teilchen zurücklegte, war die Notwendigkeit die durch die Belichtung entstehende Erwärmung der Suspension auf ein Minimum zu reduzieren.

Nicht zuletzt weil Seddig auf geliehene Mikroskope zurückgreifen musste, die es pfleglich zu behandeln galt, war er in den Möglichkeiten der Erhitzung seiner Präparate, der auch das Mikroskop selbst ausgesetzt gewesen wäre, eingeschränkt. Schließlich stellte eine auf einer Glasplatte angebrachte und mit Praffinöl benetzte Platindrahtschleife, die mit einem sehr dünnen, als Objektträger einer Zinnoberpulver-Suspension fungierenden Glas bedeckte wurde, als Heizkörper. Ein Thermoelement in der Schleife ermittelte die Temperatur.

Als Ergebnis erhielt Seddig Werte, die im Mittel 6% größere Teilchenbewegungen, als aufgrund Einsteins theoretischer Annahme erwartet, verzeichneten. Seddig erklärt dies über die Tatsache, dass durch ausstrahlende Wärme die suspendierten Teilchen stärker erwärmt würden und durch Abgabe dieser Wärme an ihre direkte Umgebung mehr Bewegung verzeichneten, als es die gemessene Durchschnittstemperatur der Suspension vermuten ließe. Unter dieser Deutung der Abweichungen sieht Seddig seine Ergebnisse als experimentelle Bestätigung der kinetischen Wärmetheorie an.
In Anlehnung an Seddigs Experiment entsteht für unser Projekt die Idee, die untere Grenze unserer Teilchenbad-Simulation mit einer „Heizfunktion“ zu versehen. Stoßen Teilchen an diese Grenze, wird ihre Geschwindigkeit im Sinne einer „Erwärmung“ erhöht.

Projektziele

  • Teilchenbewegung in einem Teilchenbad simulieren, mit korrekten Stößen (Elastischer Stoß)
  • viele kleine Teilchen und ein brownsches Teilchen mit größerer Masse simulieren
  • „Heizdraht“, der von einer Seite zusätzliche Wärmeenergie in das Bad gibt
  • Aufzeichnung der Geschwindigkeiten und Visualisierung in einem Balkendiagramm, im besten Fall maxwellsche Geschwindigkeitsverteilung wiederzuerkennen

Projektverlauf

Zuerst haben wir die Simulation eines Teilchenbads mit dem Turtle-Paket programmiert. Diese Version lief noch sehr langsam, war rucklig und hatte einige Bugs. In dieser Version hatten wir aber schon Massen für die Teilchen und die Formel für den Elastischen Stoß eingebaut.

Wir haben uns dann relativ schnell dazu entschieden auf das Paket Pygame umzusteigen. Es war zunächst eine Herausforderung sich in die Syntax von Pygame einzuarbeiten, das hat aber nach einiger Zeit gut geklappt. Unsere erste Version in Pygame lief schon deutlich flüssiger als die in Turtle und wir haben auch ein größeres und massereicheres Brownsches Teilchen eingefügt. Dort hat aber die Kollision gar nicht mehr funktioniert, die Teilchen sind alle durcheinander durchgeflogen.

Wir haben, um den Code zu verstehen, den Grund-Code von Marcel nachprogrammiert, dieser war ebenfalls in Pygame geschrieben. Dafür haben wir eine Weile benötigt: ca. bis zum 13.03.2023. Jasper hatte die Idee, sich in dem Projekt mit dem Zusammenhang von Temperatur auf die Brownsche Bewegung zu befassen. Herr Dr. Jähnert hat unserer Gruppe dann mehrere Quellen zur Verfügung gestellt, welche von Seddig verfasst wurden und sich mit der Temperaturabhängigkeit der Brownschen Bewegung befassen. In einer der Quellen wurde ein Versuch beschrieben, in welchem die Temperatur auf eine Suspension mithilfe eines Heizdrahtes verändert/eingestellt wurde. Diese Quelle war unsere Hauptquelle. Wir haben uns dann entschieden, einen Heizdraht in unsere Grundversion des Codes einzubauen. Dies wurde erreicht in dem wir bei der Kollision der Teilchen mit einer bestimmten Wand auf den Geschwindigkeitsvektor des jeweiligen Teilchen proportionsgerecht einen gewissen Faktor addiert haben, dieser heißt im Code „v_add“.

Weiter haben wir eingebaut, dass nach Abbruch der Simulation die Geschwindigkeiten der einzelnen Teichen Festgehalten wird und in gerundeter Form als Balkendiagramm geplottet wird. In diesem Balkendiagramm wurde die Anzahl der Teichen über den zugehörigen Geschwindigkeiten aufgetragen. Es ergab sich, so man die Simulation einige zeit laufen ließ, dass eine Verteilung in dem Diagramm entstand, welche grob der Maxwell-Boltzmann-Verteilung ähnelte.

Code

import random
import numpy as np
import pygame
import matplotlib.pyplot as plt
import collections

pygame.init()

# Fenster festlegen
WIDTH, HEIGHT = 700, 400
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Brownsche Bewegung")

# Farbwerte
RED = (255, 82, 32)
BLACK = (0, 0, 0)
BLUE = (23, 2, 255)
WHITE = (255, 255, 255)
GREEN = (50, 205, 50)
YELLOW = (255, 255, 0)

FPS = 60

# Werte für Teilchen
ballAmount = 100
ballRadius = 3
ballColor = BLUE
ballMasse = 10
SPEED = 2

BROWNSCHES_TEILCHEN_COLOR = RED
BROWNSCHES_TEILCHEN_RADIUS = 10
BROSCNHES_TEILCHEN_MASSE = 50


class Teilchen:
    def __init__(self, color, radius, masse):
        self.color = color
        self.radius = radius
        # zufällige Postion zuordnen
        self.x = random.randint(radius, WIDTH - radius)
        self.y = random.randint(radius, HEIGHT - radius)
        self.xy = np.array([self.x, self.y])
        # zufälliger normierter Geschwindigkeitsvektor 
        self.vxy = np.array([random.uniform(-1, 1), random.uniform(-1, 1)])
        norm = np.sqrt(self.vxy[0]**2 + self.vxy[1]**2)
        self.vxy = self.vxy / norm
        self.masse = masse
        # Zeitschritt
        self.speed = SPEED
        
    def draw(self, win):
        '''zeichnet das Teilchen ins Fenster'''
        pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)
        
    def move(self):
        """neue Koordinaten werden berechnet durch Multiplikation vom
        Geschwindigkeitsvektor und dem Zeitschritt"""
        self.x += self.vxy[0] * self.speed
        self.y += self.vxy[1] * self.speed
           
    def borderCollision(self, stepcount):
        """"Kollision mit einer Wand""" 
        if self.x >= WIDTH - self.radius:
          self.x = WIDTH - self.radius
          self.vxy[0] *= -1
        elif self.x <= self.radius:
          self.x = self.radius
          self.vxy[0] *= -1
        if self.y >= HEIGHT - self.radius:
          self.y = HEIGHT - self.radius
          self.vxy[1] *= -1
        elif self.y <= self.radius:
          self.y = self.radius
          self.vxy[1] *= -1
          
          if stepcount <= 500:
              """wenn das Teilchen weniger als 400 Schritte gemacht hat und 
              an die obere border stößt, wird der Geschwindigkeitsvektor 
              um einen bestimmten Betrag erhöht"""
              v_add = 1
              betrag = np.sqrt(self.vxy[0]**2 + self.vxy[1]**2)
              betrag_neu = betrag + v_add
              verhaeltnis = self.vxy[0] / self.vxy[1]
              if self.vxy[0] > 0:
                  self.vxy[0] = np.sqrt(((verhaeltnis**2) * (betrag_neu**2)) / (verhaeltnis**2 +1))
                  self.vxy[1] = self.vxy[0] / verhaeltnis
              elif self.vxy[0] < 0:
                 self.vxy[0] = -np.sqrt(((verhaeltnis**2) * (betrag_neu**2)) / (verhaeltnis**2 +1))
                 self.vxy[1] = self.vxy[0] / verhaeltnis
              else:
                 self.vxy[1] += v_add
    
    def ballCollision(self, ball2):
        # Zwischenspeichern der Koordinaten
        x_b1 = self.x
        y_b1 = self.y
        x_b2 = ball2.x
        y_b2 = ball2.y
        
        sv_x = ball2.x - self.x
        sv_y = ball2.y - self.y
        distance = np.sqrt(sv_x**2 + sv_y**2)
        
        if distance <= self.radius + ball2.radius:
            vxy_b1 = self.vxy
            vxy_b2 = ball2.vxy
            
            # zurücksetzen der Koordinaten auf die im Zwischenspeicher
            self.x = x_b1
            self.y = y_b1
            ball2.x = x_b2
            ball2.y = y_b2
            
            """Berechnen der neuen Geschwindigkeitsvektoren durch Formel für den elastischen Stoß"""
            self.vxy = (self.masse * vxy_b1 + ball2.masse *
                         (2 * vxy_b2 - vxy_b1)) / (self.masse + ball2.masse)
            ball2.vxy = (ball2.masse * vxy_b2 + self.masse *
                         (2 * vxy_b1 - vxy_b2)) / (self.masse + ball2.masse)
        
         
        
def draw(win, balls):
    win.fill(BLACK)
    for ball in balls:
        ball.draw(win)
    pygame.display.update()
    
                  

def main(): 
    run = 1
    
    # Teilchenobjekte in eine Liste schreiben
    balls = []
    for i in range(ballAmount):
        ball = "ball"+str(i)
        ball = Teilchen(ballColor, ballRadius, ballMasse)
        balls.append(ball)
    
    brownschesTeilchen = Teilchen(BROWNSCHES_TEILCHEN_COLOR, BROWNSCHES_TEILCHEN_RADIUS, 
                                  BROSCNHES_TEILCHEN_MASSE)
    balls.append(brownschesTeilchen)
        
    global stepcount
    stepcount = 0
                    
                
    while run:
        draw(WIN, balls)
        pygame.time.Clock().tick(FPS)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = 0
                break
        
        for ball in balls:
            ball.borderCollision(stepcount)
            for i in range(balls.index(ball) + 1, len(balls)): 
                ball.ballCollision(balls[i])                
            ball.move()
        # zählt jeden Schritt, den ein   einzelnes Teilchen macht 
        stepcount += 1
            
        # erstellt Liste aus allen Geschwindigkeiten und gibt sie aus wenn das Programm geschlossen wird    
        vballs_list = []
        for ball in balls:
            vnorm = np.sqrt(ball.vxy[0]**2 + ball.vxy[1]**2)
            vballs_list.append(round(vnorm))
            
    
    print(vballs_list)
    
    # erstellt dictionary, das Anzahl der Geschwindigkeiten zählt
    vcounter = collections.Counter(vballs_list)
    print(vcounter)
    
    # Schlüssel mit dem maximalen Wert aus dem dictionary vcounter
    häufigkeiten = vcounter.items()
    häufigkeiten = sorted(häufigkeiten)
    x, y = zip(*häufigkeiten)
    
    plt.plot(x, y)
    plt.show()
    
    pygame.quit()


if __name__ == '__main__':
    main()

brown_pygame5.py.zip

Protokolle

Bildquellen

ws2223/projekt_temperaturveraenderung.txt · Zuletzt geändert: 2023/08/12 01:40 von JasperMittag