【发布时间】:2018-05-04 20:13:49
【问题描述】:
我正在尝试用 python 构建一个核反应堆模型(不是很精确,只是为了学习和玩乐)。我正在关注这个model。
到目前为止,我已经构建了基本的主框架。燃料、中子,以及基本的东西,比如电路板和边框。您可能知道,当一个中子撞击适当的元素时,它能够将该元素一分为二,并产生一个(或几个)更多的中子。我在我的代码中应用了相同的概念,当一个中子撞击燃料粒子时,会产生另一个中子。但我现在面临的问题是,当我在屏幕上看到一定数量的中子时,模拟开始变慢,直到无法忍受。
我一直在查看我的代码,试图提高它的效率,但我找不到会导致这种情况的特定或特殊的东西。
我的代码:
import turtle
from random import randint
class Reactor:
def __init__(self, spendfuel, board, startNeut, iterr, percent_fuel):
self.fuel = []
self.fuel_t = self.newParticle('red','square',0,0)
self.spendfuel = spendfuel
turtle.setup(board[0]+200,board[1]+200), turtle.title("Reactor Top Down Reaction Model")
self.fuel,self.neutrons = self.setup(percent_fuel,board[0]//2,board[1]//2,1)
for i in range(iterr):
self.react(board[0]//2, board[1]//2)
if (len(self.neutrons) == 0):
return
turtle.update()
def setup(self, percent_fuel, x_length, y_length, neutronsNum):
turtle.bgcolor("black"), turtle.tracer(0,0)
for row in range(-x_length,x_length,4):
for column in range(y_length,-y_length,-4):
if (percent_fuel > randint(0,100)):
self.fuel_t.goto(row,column)
s_id = self.fuel_t.stamp()
s_pos = self.fuel_t.pos()
self.fuel.append([s_id,s_pos])
self.fuel_t.color('sienna')
self.neutrons = [ self.newParticle('yellow','circle',randint(-x_length,x_length),randint(-y_length,y_length)) for neutron in range(neutronsNum)]
turtle.update()
return self.fuel,self.neutrons
def react(self, x_length, y_length):
self.power = 0
for index,neutron in enumerate(self.neutrons):
x_pos = int(neutron.xcor())
y_pos = int(neutron.ycor())
inside_border = False
if ((-x_length <= x_pos) and (x_pos <= x_length) and (-y_length <= y_pos) and (y_pos <= y_length)):
inside_border = True
neutron.fd(2)
start = 0
if (x_pos <= 0 and y_pos >= 0): #Start the search for a nearby uranim from the current neutron's quad.
start = 0
elif (x_pos < 0 and y_pos < 0):
start = len(self.fuel) // 4
elif (x_pos > 0 and y_pos > 0):
start = len(self.fuel) // 2
else:
start = int(len(self.fuel) // 1.3333)
for i in range(start,len(self.fuel)-1):
if (neutron.distance(self.fuel[i][1]) <= 1):
self.fission(neutron,i,self.neutrons)
break
if not(inside_border):
self.neutrons.remove(neutron)
neutron.ht()
def fission(self, neutron, index, neutrons):
neutron.rt(randint(0,360))
if (self.spendfuel):
self.fuel_t.goto(self.fuel[index][1])
self.fuel_t.stamp()
self.fuel.pop(index)
neutrons.append(self.newParticle('yellow','circle',neutron.xcor(),neutron.ycor()))
neutrons[-1].rt(randint(0,360))
def newParticle(self, color, shape, row, column):
t = turtle.Pen() #New turltle type object
t.pu(), t.speed(10), t.ht(), t.color(color), t.shape(shape), t.shapesize(0.125,0.125,0.125)
t.goto(row,column), t.st()
return t
if __name__ == "__main__":
g = Reactor(False, [400,400], 1, 300, 10)
如果能帮我解决这个问题,让我的模型运行得更快,我将不胜感激。同样重要的是,中子与turtle.stamp() 的燃料颗粒不同,是乌龟物体。中子用颜色表示——黄色——而燃料粒子用颜色表示——红色——
【问题讨论】:
-
代码太多了。此外,它不会按原样运行。如果你修复了明显的缩进错误,它会运行,但会立即退出,所以它仍然不能证明你所问的问题。请阅读帮助中的minimal reproducible example。
-
我修复了缩进并放置了我的代码的旧版本始终可以工作,我之前遇到的版本在产生第一个中子时遇到了一些麻烦,对此感到抱歉。 @abarnert
-
代码还是太多了。您需要弄清楚如何将其简化为证明问题所需的基本要素。没有这个,我可以做出一些猜测(例如,你是在裂变中子,然后在移除燃料之前检查新的中子吗?),但它们只是疯狂的猜测,没有大量的调试工作来缩小范围。
-
@OmerHen 您确实在“self.fission”行之外有一个(嵌套)循环。 if 条件很可能比您预期的更频繁地评估为真。我在那里放了一个打印声明,并得到了很多打印输出。将您的幻数从 2 调整为其他值。
-
我缩小了代码范围。在我遵循的模型中(您可以在帖子中找到链接),默认设置是当中子撞击燃料时,它们不会浪费它,它们只是分裂并且燃料保持完整。因此,我尝试遵循相同的程序。 @abarnert
标签: python python-3.x turtle-graphics