Python 基于dask的高效n体仿真

Python 基于dask的高效n体仿真,python,dask,Python,Dask,用于模拟涉及粒子相互作用的物理系统的动力学,或将问题简化为具有物理意义的某种粒子。粒子可以是气体分子,也可以是星系中的恒星。Dask.bag提供了一种在群集中分布粒子的简单方法,例如,为Dask.bag.from_sequence()提供一个自定义迭代器,该迭代器返回粒子对象: class ParticleGenerator(): def __init__(self, num_of_particles, max_position, seed=time.time()): r

用于模拟涉及粒子相互作用的物理系统的动力学,或将问题简化为具有物理意义的某种粒子。粒子可以是气体分子,也可以是星系中的恒星。Dask.bag提供了一种在群集中分布粒子的简单方法,例如,为
Dask.bag.from_sequence()
提供一个自定义迭代器,该迭代器返回粒子对象:

class ParticleGenerator():
    def __init__(self, num_of_particles, max_position, seed=time.time()):
        random.seed(seed)
        self.index = -1
        self.limit = num_of_particles
        self.max_position = max_position
    def __iter__(self):
        return self 
    def __next__(self):
         self.index += 1
         if self.index < self.limit :
             return np.array([self.max_position*random.random(), self.max_position*random.random(), self.max_position*random.random()]) 
         else :
             raise StopIteration
b = db.from_sequence( ParticleGenerator(1000, 1, seed=123456789) )
对于CompleteMode,这是
更新位置
功能:

def update_position(e, others=None, mass=1, dt=1e-4):
    f = np.zeros(3)
    for o in others:
        r = e - o
        r_mag = np.sqrt(r.dot(r))
        if r_mag == 0 :
            continue 
        f += ( A/(r_mag**7) + B/(r_mag**13) ) * r
    return e + f * (dt**2 / mass)
A
B
一些任意值
dask.bag.map()
可以在循环内多次调用以执行模拟

  • Dask.bag
    是处理此类问题的一个很好的集合(抽象)吗?也许Dask是个更好的主意
  • 通过这种方式编程模拟,调度器是否处理所有通信,或者位置、速度等信息是否与工作人员间通信共享
  • 对优化代码有何评论?特别是关于调用
    dask.bag.map()
    时将集合转换为列表的过热问题
    一般来说,N体模拟需要复杂的算法和数据结构才能有效运行。许多常见的解决方案包括使用复杂的树数据结构。您可能需要搜索kd tree或barnes hut之类的术语

    另一方面,Dask.bag是您可以想象的最简单/最愚蠢的并行编程抽象之一,类似于MapReduce和Spark等其他批量数据处理系统。这些系统不够灵活,无法在N体模拟等复杂问题上提供良好的性能

    类似于或的东西将提供更大的灵活性,但即使是这些也不会与经过微调的KD树相同

    def update_position(e, others=None, mass=1, dt=1e-4):
        f = np.zeros(3)
        for o in others:
            r = e - o
            r_mag = np.sqrt(r.dot(r))
            if r_mag == 0 :
                continue 
            f += ( A/(r_mag**7) + B/(r_mag**13) ) * r
        return e + f * (dt**2 / mass)