Je suis un étudiant en aérospatiale travaillant sur un projet d'école pour notre cours de programmation python. L'affectation est créer un programme en utilisant seulement Pygame et numpy. J'ai décidé de créer une simulation en soufflerie qui simule le flux d'air sur une aile bidimensionnelle. Je me demandais s'il y avait une façon plus efficace de faire le calcul d'un point de vue de la programmation. Je vais vous expliquer le programme:simulation de soufflerie plus efficace dans Pygame, en utilisant numpy
Le champ (stable) d'écoulement est modélisé à l'aide de la méthode du panneau de vortex. Fondamentalement, j'utilise une grille de Nx fois Ny points où à chaque point un vecteur de vitesse (u, v) est donné. Ensuite, en utilisant Pygame, je cartographie ces points de la grille comme des cercles, de sorte qu'ils ressemblent à une zone d'influence. Les points de la grille sont les cercles gris dans l'image suivante:
I créer des particules de N et de déterminer leurs vitesses par itération comme suit:
créer une liste de particules.
créer une liste de grille.
pour chaque point de grille dans la liste de la grille:
pour chaque particule dans la liste des particules:
si particules A se situe dans la zone d'influence du point de grille n (xn, yn):
particule A sa vitesse = vitesse au point de grille n.
Visualisez tout dans Pygame. Cette méthode de base était la seule façon dont je pouvais penser à visualiser le flux dans Pygame. La simulation fonctionne plutôt bien, mais si j'augmente le nombre de points de la grille (augmente la précision du champ d'écoulement), la performance diminue. Ma question est de savoir s'il existe un moyen plus efficace de le faire en utilisant simplement pygame et numpy?
Je joins le code ici:
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()
Le code requiert un autre script qui calcule le champ d'écoulement lui-même. Il lit également les points de données d'un fichier texte pour obtenir la géométrie de l'aile. Je n'ai pas fourni ces deux fichiers, mais je peux les ajouter si nécessaire. Merci d'avance.
Donc, votre seule question est de savoir comment le rendre plus efficace? –
Bienvenue dans le monde des CFD. Il existe différentes façons d'accélérer les choses, mais de manière générale: elles impliquent beaucoup de recodage. Si c'est ce que vous voulez pour votre projet d'étudiant, allez-y, ça vaut le coup! Jetez un oeil à d'autres frameworks (OpenFOAM, par exemple). En particulier, le calcul couplé directement avec la visualisation ne fonctionnera pas avec des simulations plus intensives en calcul. Mais bon travail! –
cricket_007 oui, mais seulement en utilisant Pygame et numpy ses fonctionnalités. Jens Höpken, merci. J'ai lu récemment sur OpenFOAM. Je vais certainement jeter un coup d'oeil. – Sami