Ich bin ein Student der Luft- und Raumfahrt, der an einem Schulprojekt für unseren Python-Programmierkurs arbeitet. Die Zuweisung ist ein Programm nur mit Pygame und numpy erstellen. Ich beschloss, eine Windkanalsimulation zu erstellen, die den Luftstrom über einem zweidimensionalen Flügel simuliert. Ich habe mich gefragt, ob es eine effizientere Möglichkeit gibt, die Berechnung aus einer Programmierperspektive zu machen. Ich werde das Programm erklären:effizientere Windtunnelsimulation in Pygame, mit numpy
ich hier ein Bild beigefügt habe:
Das (steady) Strömungsfeld ist die Wirbelplatte Methode modelliert. Grundsätzlich benutze ich ein Gitter von Nx mal Ny Punkten, wo an jedem Punkt ein Geschwindigkeits- (u, v) Vektor gegeben ist. Mit Pygame mappe ich dann diese Gitterpunkte als Kreise, so dass sie einem Einflussbereich ähneln. Die Gitterpunkte sind die grauen Kreise in dem folgenden Bild:
I N Partikel erzeugen und ihre Geschwindigkeiten bestimmen durch Iterieren wie folgt:
eine Liste von Partikeln erstellen.
erstellen Sie eine Rasterliste.
für jeden Gitterpunkt in Gittern:
für jeden Partikel in der Liste der Teilchen:
wenn liegt Teilchen A im Bereich des Einflusses des Gitterpunkt n (xn, yn):
Partikel A seine Geschwindigkeit = Geschwindigkeit am Gitterpunkt n.
Visualisieren Sie alles in Pygame.
dieser grundlegende Weg war der einzige Weg, wie ich den Fluss in Pygame visualisieren konnte. Die Simulation funktioniert ziemlich gut, aber wenn ich die Anzahl der Gitterpunkte (erhöhen Sie die Genauigkeit des Strömungsfeldes) erhöhen, sinkt die Leistung. Meine Frage ist, ob es einen effizienteren Weg gibt, dies zu tun, nur mit Pygame und Numpy?
Ich habe den Code hier angebracht:
import pygame,random,sys,numpy
from Flow import Compute
from pygame.locals import *
import random, math, sys
#from PIL import Image
pygame.init()
Surface = pygame.display.set_mode((1000,600))
#read the airfoil geometry from a dat file
with open ('./resources/naca0012.dat') as file_name:
x, y = numpy.loadtxt(file_name, dtype=float, delimiter='\t', unpack=True)
#parameters used to describe the flow
Nx=30# 30 column grid
Ny=10#10 row grid
N=20#number of panels
alpha=0#angle of attack
u_inf=1#freestream velocity
#compute the flow field
u,v,X,Y= Compute(x,y,N,alpha,u_inf,Nx,Ny)
#The lists used for iteration
Circles = []
Particles= []
Velocities=[]
#Scaling factors used to properly map the potential flow datapoints into Pygame
magnitude=400
vmag=30
umag=30
panel_x= numpy.multiply(x,magnitude)+315
panel_y= numpy.multiply(-y,magnitude)+308
#build the grid suited for Pygame
grid_x= numpy.multiply(X,magnitude)+300
grid_y= numpy.multiply(Y,-1*magnitude)+300
grid_u =numpy.multiply(u,umag)
grid_v =numpy.multiply(v,-vmag)
panelcoordinates= zip(panel_x, panel_y)
# a grid area
class Circle:
def __init__(self,xpos,ypos,vx,vy):
self.radius=16
self.x = xpos
self.y = ypos
self.speedx = 0
self.speedy = 0
#create the grid list
for i in range(Ny):
for s in range(Nx):
Circles.append(Circle(int(grid_x[i][s]),int(grid_y[i][s]),grid_u[i][s],grid_v[i][s]))
Velocities.append((grid_u[i][s],grid_v[i][s]))
#a particle
class Particle:
def __init__(self,xpos,ypos,vx,vy):
self.image = pygame.Surface([10, 10])
self.image.fill((150,0,0))
self.rect = self.image.get_rect()
self.width=4
self.height=4
self.radius =2
self.x = xpos
self.y = ypos
self.speedx = 30
self.speedy = 0
#change particle velocity if collision with grid point
def CircleCollide(Circle,Particle):
Particle.speedx = int(Velocities[Circles.index((Circle))][0])
Particle.speedy = int(Velocities[Circles.index((Circle))][1])
#movement of particles
def Move():
for Particle in Particles:
Particle.x += Particle.speedx
Particle.y += Particle.speedy
#create particle streak
def Spawn(number_of_particles):
for i in range(number_of_particles):
i=i*(300/number_of_particles)
Particles.append(Particle(0, 160+i,1,0))
#create particles again if particles are out of wake
def Respawn(number_of_particles):
for Particle in Particles:
if Particle.x >1100:
Particles.remove(Particle)
if Particles==[]:
Spawn(number_of_particles)
#Collsion detection using pythagoras and distance formula
def CollisionDetect():
for Circle in Circles:
for Particle in Particles:
if Particle.y >430 or Particle.y<160:
Particles.remove(Particle)
if math.sqrt(((Circle.x-Particle.x)**2) + ((Circle.y-Particle.y)**2) ) <= (Circle.radius+Particle.radius):
CircleCollide(Circle,Particle)
#draw everything
def Draw():
Surface.fill((255,255,255))
#Surface.blit(bg,(-300,-83))
for Circle in Circles:
pygame.draw.circle(Surface,(245,245,245),(Circle.x,Circle.y),Circle.radius)
for Particle in Particles:
pygame.draw.rect(Surface,(150,0,0),(Particle.x,Particle.y,Particle.width,Particle.height),0)
#pygame.draw.rect(Surface,(245,245,245),(Circle.x,Circle.y,1,16),0)
for i in range(len(panelcoordinates)-1):
pygame.draw.line(Surface,(0,0,0),panelcoordinates[i],panelcoordinates[i+1],3)
pygame.display.flip()
def GetInput():
keystate = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT or keystate[K_ESCAPE]:
pygame.quit();sys.exit()
def main():
#bg = pygame.image.load("pressure.png")
#bg = pygame.transform.scale(bg,(1600,800))
#thesize= bg.get_rect()
#bg= bg.convert()
number_of_particles=10
Spawn(number_of_particles)
clock = pygame.time.Clock()
while True:
ticks = clock.tick(60)
GetInput()
CollisionDetect()
Move()
Respawn(number_of_particles)
Draw()
if __name__ == '__main__': main()
Der Code erfordert ein anderes Skript, das das Strömungsfeld selbst berechnet. Es liest auch Datenpunkte aus einer Textdatei, um die Geometrie des Flügels zu erhalten. Ich habe diese zwei Dateien nicht zur Verfügung gestellt, aber ich kann sie bei Bedarf hinzufügen. Vielen Dank im Voraus.
So Ihre einzige Frage ist, wie es effizienter zu machen? –
Willkommen in der CFD-Welt. Es gibt verschiedene Wege, die Dinge zu beschleunigen, aber allgemein gesprochen: Sie beinhalten eine Menge Neucodierung. Wenn es das ist, was Sie für Ihr Studentenprojekt wollen, dann gehen Sie darauf, es lohnt sich! Sehen Sie sich andere Frameworks an (zum Beispiel OpenFOAM). Insbesondere die Berechnung, die direkt mit der Visualisierung gekoppelt ist, wird nicht mit rechenintensiveren Simulationen funktionieren. Aber toller Job! –
cricket_007 ja, aber nur mit Pygame und numpy seine Funktionalitäten. Jens Höpken, danke. Ich habe erst vor kurzem über OpenFOAM gelesen. Ich werde es mir auf jeden Fall ansehen. – Sami