我已经开始使用python作为编程语言来执行CFD中的所有作业。我在编程方面经验很少。我来自机械工程领域,正在从事航空航天工程的高等教育。
有时,CFD的计算方面比处理方程式或进行数学运算更乏味。
有哪些一般准则可以使我们的程序运行更快?做并行处理的技巧是什么?如何编写运行速度更快的代码?
我在哪里可以得到回答上述问题的资源(对于像我这样的外行人来说很容易理解)?
我已经开始使用python作为编程语言来执行CFD中的所有作业。我在编程方面经验很少。我来自机械工程领域,正在从事航空航天工程的高等教育。
有时,CFD的计算方面比处理方程式或进行数学运算更乏味。
有哪些一般准则可以使我们的程序运行更快?做并行处理的技巧是什么?如何编写运行速度更快的代码?
我在哪里可以得到回答上述问题的资源(对于像我这样的外行人来说很容易理解)?
Answers:
考虑到您专门要求使用Python,我将尝试回答您的问题。我将描述自己解决模拟问题的方法。本说明中给出了用于更快仿真的策略。
首先,我用Python制作了新的模拟原型。当然,我会尽量利用NumPy和SciPy。NumPy提供了适合于数值模拟的数组数据类型,而SciPy提供了适用于NumPy数组的广泛数值例程。
一旦原型工作或多或少,我将尝试了解程序或脚本的哪些部分是瓶颈。有典型的候选人:
我使用一种简单的分析策略来了解所有运行时间都花在了哪里。使用IPython shell(我不能推荐足够多的东西),我使用
%timeit script.py
这个“魔术命令”将为您进行性能分析(使用timeit),并在脚本终止后向您显示带有时间的列表。使用此列表可以找出您的代码太慢的地方。
一旦确定了需要加速的部分,就可以考虑使用编译语言。我将指出两个解决方案。
首先,有Cython语言。Cython是一种非常类似于Python的编程语言(实际上,Python代码通常也是有效的Python代码);但是,Cython编译器将Cython文件转换为C代码,然后可以将其编译为可从Python使用的模块。Cython了解NumPy数组。使用Cython可以通过两种方式为您提供帮助:首先,您可以介绍数据类型。这将加速函数调用。同样,如果您遍历数组,则循环将运行得更快(实际上,如果同时输入了哑变量和数组,则会得到普通的C循环!)。其次,在我的实验中,甚至无类型脚本的运行速度也要快一些,因为它们是编译而不是解释的。
对您有用的另一种编译语言是Fortran。将Fortran与Python结合使用的方式有多种(f2py,fortwrap,Cython)。就我个人而言,f2py似乎是最简单的方法,我将快速描述它的作用。f2py可以将Fortran代码编译为Python模块。它将允许您将NumPy数组用作Python空间中的输入和输出变量。在Fortran空间中,这些将是普通的Fortran阵列。您可以全速运行Fortran。
就个人而言,我倾向于使用Cython,其中函数调用的数量是瓶颈。对于繁重的工作,我更喜欢f2py(也许是因为我有很强的Fortran背景)。
关于Fortran的其他说明:现代Fortran的读取和写入与NumPy非常相似-语法非常接近。这使得将NumPy代码转换为Fortran代码变得容易。
请注意,Cython和f2py都以某种方式支持并行处理。对于Cython,您将在这里找到帮助,而对于Fortran,则有诸如OpenMP或MPI之类的标准技术。此外,也有用于MPI的 P ython包装器。就个人而言,我在Python级别上使用mpi4py以及在Fortran中使用OpenMP。
让我推荐一些文献:H.-P着的《计算科学的Python脚本》一书。总体而言,Langtangen是有关Python以及关于使Python更快一点的策略的重要资源。不幸的是,AFAIR没有在Cython上提及任何内容。在我作为第二篇资源时,您可能会看到这些幻灯片。这些给出了我在本文中提到的所有内容的示例(另请参见此处的代码和源代码)。互联网上还有许多其他不错的幻灯片。
如果您还有其他具体问题,我们很乐意为您提供帮助!
对于CFD + Python,有一个解决方案:http : //pythonflu.wikidot.com/这些是OpenFOAM之上的Python绑定(在问题注释中已经提到)。这些绑定允许在“求解器级别”上进行编程(有些示例在Python中复制了原始OpenFOAM求解器,并且它们的运行速度不比原始版本慢-另一个答案中提到的慢循环在这里不是问题,因为发生了“内部循环”在OpenFOAM的C ++代码中)。
这些绑定的优点还在于,OpenFOAM中的所有并行化都在求解器级别下进行,因此您不必为它烦恼(以及OpenFOAM核心要处理的其他内容:输入/输出,线性求解器,算子离散化)
因此,如果您只想编写一个新的求解器而又不向OF核添加新功能(边界条件,线性求解器等),那么PythonFlu可能就足够了,您可以避免使用C ++(它的学习方法比蟒蛇)
PS:本来想将此添加为对原始问题的讨论的评论,但我的声誉不允许我这样做