有限体积代码的数据结构:数组与类


11

我必须为磁流体动力学(MHD)编写一个有限的体积代码。我以前写过数字代码,但没有达到这个规模。我只是想问一问,使用具有类的数据结构(面向对象的方法),或者只是针对速度,可伸缩性等对多个属性使用多个数组,这将是一个不错的选择。我打算用python编写代码,并且将fortran用于数字密集型部分。

python中的类的示例是

class Cell:
   def __init__(self, x, y, z, U):

数组可以简单地定义为

x[nx][ny][nz]
y[nx][ny][nz]
z[nx][ny][nz]
U[nx][ny][nz]

等等

Answers:


9

简单的答案:在现代python中,每种数据类型都是一个类,因此,在您提出的两种解决方案之间,形式上没有区别。(请记住使用新型类:经典类已过时!请参见http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes

现在的问题应该是:如何在python中组织有效的数据结构?毫无疑问的是组织细胞作为阵列的想法class Cell实例是低效。最终,您将得到一堆混乱的指针和不连续的数据,就像复杂的链表一样。您当然可以轻松地在列表中插入新单元格:但是您需要此功能吗?相反,您将拥有不连续的数据存储,并且必须通过不同级别的间接访问每个单元。

如果您将数据组织为,numpy.ndarray则数据是内存连续的,访问不同的单元格只是简单地跨越内存块:空间高效(指针不浪费内存)且速度很快

正如Ethan所指出的,应该使用OO概念,但是在更高级别上,一旦实现了有效的低级别数据结构(通常通过numpy.ndarray)即可。

OO编程意味着将数据绑定到在更高抽象层上对数据本身进行操作的方法。(示例:我实现了FEM代码,其中使用一种稀疏超节点cholesky分解方法将刚度矩阵定义为一类。第一种实现是内核内:当需要内核外实现时,是通过继承和底层数据存储的最小调整而获得的。几乎100%的超节点cholesky代码都得到了重用。)

最后但至关重要的一点是:有效的数值过程是算法和数据结构与目标计算体系结构智能映射的结果。如果您从错误的数据结构开始,那么没有完整的重写就无法恢复效率。


@EthanCoon感谢您对其他答案的评论,这使我编写了自己的答案。
Stefano M

10

我几天前也在考虑这一点(同样在Python中)。我个人并不认为面向对象的编程总是适合数字编程。设计类可能会分散您的注意力,而不仅仅是求解方程式。我更喜欢简单的函数,使用numpy可以将方程矢量化,因此所需的行数很少。Numpy非常快,因为实际的计算是使用C(或FORTRAN?)后端完成的。

我会建议你做的

  1. 编写一个Python脚本,使用numpy的函数方法来解决问题的最简单版本。例如,将所有内容都设为任意单位,然后仅尝试1D(或2D)。如果代码凌乱,在此阶段就可以了。重要的是您正在推进项目。
  2. 一旦您有了可行的东西。标识代码在哪里冗长和难懂。在此阶段,您可以尝试各种有关如何简化代码的想法。也许在您发现自己在重复自己的地方引入功能。您可以将其与原始版本进行比较,从而知道您没有引入错误。
  3. 确定面向对象的方法是否会进一步降低代码的复杂性。

主要信息是,除非您已经以最简单的方式解决了问题,否则不要开始编写类。只有通过获得解决问题的经验,您才能知道如何定义面向对象的接口。如果您事先进行此操作,则很可能会遇到麻烦。


3
我非常不同意OO不适用于数值编程的说法,但是在更高的层次上,OO非常适合。OO对于诸如物理模型,网格,求解器之类的东西非常有用,但是在单元级别几乎总是不合适的。
伊桑·库恩

在这篇文章中,我想警告数字代码“过早地物化”可能会陷入困境,尤其是当人们开始学习时。我并不反对使用对象,请看我的第三点:如果对象可以降低复杂性,那么它们是一个好主意。我同意您引用的示例是很好的用法,但是达到这一点需要经验。
boyfarrell 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.