python做电磁场计算_加速Python中的计算(模拟磁场中的粒子)

用Python编写的程序速度有问题。该程序是“模拟磁场中的铁磁颗粒”,更具体地说是磁惰性液体。该程序可以工作,但与用C ++编写的相同程序相比非常缓慢,但是我用Python编写了一个项目来研究。

总的来说,程序代码基于循环,有很多浮点计算。随机数量的粒子(随机产生的位置)在磁场的影响下相互作用。

这是初始职位:

决赛:

主循环(在SymMain.py中,具有k变量)迭代是时间步长,计算当时粒子在其中的坐标和作用在其上的力(吸引力和小排斥力)。为了加快速度,我想使用并行处理来同时计算迭代次数,但这是不可能的,因为一次迭代中的计算取决于前一次迭代的计算。

我不知道Python比C ++慢得多。例如,计算一次性步骤中529个粒子的模拟(在我的计算机上):

C + + ~0.5s

Python~50s

那么,如何加快程序?请帮忙。

此代码仅计算,而不是像图片中那样绘制粒子。模拟partcile的数量在SymConst.py上,这是nrH * nrL。

SymMain.py

#coding:windows-1250

from os import system

from SymCalc import *

from SymParticle import *

if __name__ == '__main__':

App = SymCalc()

App.MainLoop()

SymParticle.py

#coding:windows-1250

from random import randint

from math import *

from SymConst import *

from SymParticle import *

class SymCalc(object):

def __init__(self):

# declaration lists containing the properties of the particles

ParticleList = []

ParticleListTemp = []

t = 0.0

# the initial values ​​of particle

for x in range(0, nParticle):

ParticleList.append(Particle(x+1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 8e-6))

ParticleListTemp.append(Particle(x+1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 8e-6))

# generating random coordinates X, Y

for x in range(0, nParticle):

self.Rand(ParticleList[x], x)

# time steps

for k in range(0, k0):

print "Time step = {0}".format(k)

# calculation of forces

for i in range(0, nParticle):

for j in range(0, i-1):

self.ParticleCalculate(ParticleList[i], ParticleList[j], 1)

for j in range(i+1, nParticle):

self.ParticleCalculate(ParticleList[i], ParticleList[j], 1)

# display data

if(k%Constant == 0):

for i in range(0, nParticle):

self.Print(k, i, ParticleList[i], t)

# changing the position of the particle

for i in range(0, nParticle):

self.ChangeOfPosition (ParticleList[i], dt)

# reset forces

for j in range(0, nParticle):

self.ParticleCalculate(ParticleList[i], ParticleList[j], 0)

self.ParticleCalculate(ParticleList[i], ParticleListTemp[j], 0)

# next time step

t += dt

# random coordinates of the particles

def Rand(self, part, lp):

l = lp%nrL # współrzędna X pola

part.x = (l-nrL/2)*(L0/nrL) + ((randint(0,32767)%100)-50)*(L0/nrL-2*part.r)/99 # X

h = (lp+1-(lp)%nrL)/nrL # Y

part.y = (h-nrH/2)*(H0/nrH) + ((randint(0,32767)%100)-50)*(H0/nrH-2*part.r)/99 # współrzędna Y cząstki

# calculating function of the force acting on the particles

def ParticleCalculate(self, part, part_tmp, p):

# auxiliary variables

# r_4, dx, dy, rr, sum, sx, sy, chi_eff, tmp, frepx, frepy, f0

md = []

if(p == 0):

part.frx = 0

part.fry = 0

part.fx = 0

part.fy = 0

if(p == 1):

# versor coordinates connecting the geometrical center of the particle

dx = part.x - part_tmp.x

dy = part.y - part_tmp.y

# the distance between the geometric means of the particle

rr = sqrt(dx*dx + dy*dy)

if(rr < 0.85*(part.r + part_tmp.r)):

print "ERROR: Invalid distance between the particles! Simulation aborted..."

if(rr >= 10*part.r):

# magnetic dipoles

chi_eff = (3.*(MI_P - 1.))/((MI_P - 1) + 3.)

md.append((4.*MI_0*pi*part.r*part.r*part.r*chi_eff*M_H0)/3.0)

md.append((4.*MI_0*pi*part_tmp.r*part_tmp.r*part_tmp.r*chi_eff*M_H0)/3.0)

tmp = pow(rr,7)

# first member

sum = (5.*(md[0]*part.nx*dx + md[0]*part.ny*dy) * (md[1]*part_tmp.nx*dx + md[1]*part_tmp.ny*dy)) / tmp

sx = sum*dx

sy = sum*dy

tmp = tmp / (rr*rr)

# second member

sum = (md[0]*part.nx*md[1]*part_tmp.nx + md[0]*part.ny*md[1]*part_tmp.ny) / tmp

sx -= sum*dx

sy -= sum*dy

# third member

sx -= (md[0]*(md[1]*part_tmp.nx*dx + md[1]*part_tmp.ny*dy)*part.nx + md[1]*(md[0]*part.nx*dx + md[0]*part.ny*dy)*part_tmp.nx)/tmp

sy -= (md[0]*(md[1]*part_tmp.nx*dx + md[1]*part_tmp.ny*dy)*part.ny + md[1]*(md[0]*part.nx*dx + md[0]*part.ny*dy)*part_tmp.ny)/tmp

# finally

tmp = (-3./(4*pi*MI_0))

sx *= tmp

sy *= tmp

part.fx += sx

part.fy += sy

# short-range repulsive force

tmp = pow(rr,15)

r_4 = pow((part.r+part.r),4)

f0 = 3.*fabs(md[0])*fabs(md[1])/(4.*pi*MI_0*r_4)

frepx = pow((part.r+part.r),15)*dx/(tmp*rr)*f0

frepy = pow((part.r+part.r),15)*dy/(tmp*rr)*f0

part.frx += frepx;

part.fry += frepy;

# change the position of the particle

def ChangeOfPosition(self, part, dt):

part.ddx = 0

part.ddy = 0

part.ddx = 1/(6*pi*part.r*eta)*(part.fx+part.frx)*dt

part.ddy = 1/(6*pi*part.r*eta)*(part.fy+part.fry)*dt

# particles new position value

part.x += part.ddx

part.y += part.ddy

if(part.x < -L0/2):

part.x += L0

elif(part.x > L0/2):

part.x -= L0

elif(part.y < -H0/2):

part.y += H0

elif(part.y > H0/2):

part.y -= H0

# display data

def Print(self, k, i, part, t):

print "-"*50

print "\nParticle {0}".format(i+1)

print "The resultant magnetostatic force fx = {0}".format(part.fx - part.frx)

print "The resultant magnetostatic force fy = {0}\n".format(part.fy - part.fry)

if(i == nParticle-1):

print "\n\t\t---t={0}[s]---".format(t)

print "-"*50

SymParticle.py

#coding:windows-1250

class Particle(object):

# generating a particle properties

def __init__(self, num, x, y, fx, fy, frx, fry, nx, ny, ddx, ddy, r):

self.num = num

self.x = x

self.y = y

self.fx = fx

self.fy = fy

self.frx = frx

self.fry = fry

self.nx = nx

self.ny = ny

self.ddx = ddx

self.ddy = ddy

self.r = r

SymConst.py

#coding:windows-1250

### Constant

M_H0 = 3e4

MI_0 = 12.56e-7

MI_P = 2000

eta = 0.1

k0 = 10001

dt = 1e-6 # time step

H0 = 5.95e-4

L0 = 5.95e-4

nrH = 4

nrL = 4

Constant = 100

nParticle = nrH*nrL # number of particle

你可能感兴趣的:(python做电磁场计算)