私はPythonプログラミングコースの学校プロジェクトに取り組んでいる航空宇宙の学生です。割り当ては、Pygameとnumpyを使用しているプログラムを作成することです。私は、2次元翼上の気流をシミュレートする風洞シミュレーションを作成することに決めました。私はプログラミングの観点から計算を行うより効率的な方法があるのだろうかと思っていました。Pythonのより効率的な風洞シミュレーション、numpyを使用
(定常)流れ場 は渦パネルのメソッドを使用してモデル化され、私はプログラムを説明します。基本的には、各点で速度(u、v)ベクトルが与えられるNx倍のNy点のグリッドを使用しています。次に、Pygameを使用して、これらのグリッドポイントを円としてマッピングします。その結果、これらのグリッドポイントは影響範囲に似ています。
Iは、N個の粒子を作成し、以下のように反復することによって、それらの速度を決定する:グリッド点は、次の画像における灰色の円である
粒子のリストを作成します。
グリッドリストを作成します。粒子のリスト中の各粒子について
:グリッドリスト内の各格子点のため
粒子Aは、格子点の影響の領域内にあるN(XN、YN)場合:
粒子その速度=格子点nにおける速度。
Pygameのすべてを視覚化します。
この基本的なやり方は、私がPygameのフローを視覚化する唯一の方法でした。シミュレーションはうまくいきますが、グリッドポイントの数を増やして(フローフィールドの精度を上げると)、パフォーマンスが低下します。私の質問は、pygameとnumpyを使ってこれを行うより効率的な方法があるかどうかです。
私はここにコードを添付しています
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()
コードが流れ場自体を計算し、別のスクリプトが必要です。また、テキストファイルからデータポイントを読み取り、ウィングのジオメトリを取得します。 私はこれら2つのファイルを提供していませんが、必要に応じて追加することができます。前もって感謝します。
だからあなたの唯一の問題は、それをより効率的にする方法ですか? –
CFDの世界へようこそ。スピードアップにはさまざまな方法がありますが、一般的に言えば、多くの記録が必要です。これがあなたの学生プロジェクトのために欲しいものなら、それのために行く、それはそれの価値がある!他のフレームワーク(OpenFOAMなど)を見てみましょう。特に、視覚化と直接結合された計算は、より計算量の多いシミュレーションでは機能しません。しかし、素晴らしい仕事! –
cricket_007はい、ただし、Pygameを使用し、その機能を無効にします。 JensHöpken、ありがとう。私は最近、OpenFOAMについて読んでいます。私は間違いなく見ています。 – Sami