演算法和推导都懂,但是无法转换成计算机语言。不管是Matlab还是python都不会,每次打开电脑写作业是对著屏幕发呆最后东抄抄西抄抄,请问大家这种情况该如何改善一下?

而且这种情况不只体现在CFD上,学数值分析的时候编程也很困难……


写了好多,其实就一句话:「你没有站在计算机语言的角度理解cfd,你还是站在数学语言的角度理解cfd,包括之前的数值分析。」

先讲「理」

编程语言好歹也是一门语言。你可以把它跟一门自然语言类比,比如说拉丁语。(你也可以替换成其他不太熟的外语)那么现在你的「基于cfd理论自行写出一份cfd代码」的目标相当于「基于一个小说大纲,使用拉丁语写出这篇中篇小说」。这中间缺的不止是学会拉丁语的语法。

对于你的问题,这个类比就是

我脑子里有个小说构想,提纲主线人物关系都非常清楚,可是总是写不出来,不管是拉丁语还是阿拉伯语。每次想写又写不出来就只好上网东抄抄西抄抄。以前上中级拉丁语课程的时候,让我写一段话的小故事作文也出现过这个问题。

理想情况下,你应该在这棵技能树上依次点开五个技能点,前四个分别对应于四门课程。

第一个是一门编程语言。这一步相当于学习基本语法,主谓宾关系之类而已。

第二个是数据结构和演算法。这一步是了解计算机是如何存储和处理数据的。数据结构相当于了解词根词缀造词,或者偏旁部首组字。演算法就像是常见短语。

第三个是数值方法。使用特定的方式操作数据来完成简单数学计算功能。对应到小说中相当于写一段话,描述一个场景,或者两个人物的对话。你需要正确使用辞汇短语,还要表达连贯的意思。

第四个是计算流体力学。流体计算功能的实现需要哪些组件。其实这个课程只是相当于讲了一个小说提纲。一个常见的误解就是学了cfd课程就可以写出一份cfd代码。

第五个是软体工程的架构能力。cfd课程只是讲了cfd的组件,和它们之间的逻辑联系。但是这个逻辑联系如何用计算机语言表示出来,是不讲的。架构能力就是把一个cfd软体拆分成模块,定义数据和介面。相当于把提纲拆分成几个大的故事,并且在故事中间穿插场景的转换。

写一个cfd代码是倒过来使用上面的五项技能。首先在架构上,你要站在计算机的角度来理解cfd的计算流程。计算机只会读取、存储和操作数据。那么你如何指挥计算机按照「它的方式」读取存储和操作「它的数据」,来完成「你的想法」。你要告诉计算机一个操作流程。

在架构层面上你需要把程序拆分成若干模块。那如何知道都有哪些模块呢?cfd知识给了你一个提纲,比如你会需要一个线性方程求解器,一系列离散格式,速度压力方程的耦合,以及一系列其他物理过程的额外方程,比如湍流模型。这些还是不够的,因为你还会需要一个io,一个configuration,甚至还要一个mpi。这些是cfd教材不管的。

那么你将如何在内存中存储一个线性矩阵,一个向量,一个矢量。再复杂一点的包括,如何表示一个网格,一个压力场,速度场,一个复杂的边界条件。这些归根结底还是数据结构在cfd上的特殊应用。

在程序开始的时候你将如何读取数据,在结束时如何存储数据?注意数据在硬碟上的存储和在内存上的存储是不一样的。

你如何在时间和空间之间做权衡。比如牺牲CPU换内存,还是反过来。这是在演算法层面的内容。

线性方程求解器直接使用了数值分析的内容。除此之外,离散格式也间接使用了。我们的架构设计把离散格式放在了一个模块下面,那我们进入到这个模块中,你要把离散格式拆分成什么样的函数,既能重用函数,又不会把函数分的太碎。重用和避免太碎都是为了降低编程的工作量。

现在你终于把一个代码从最初的cfd教程提供的提纲变成了一堆数据结构和操作函数。数据结构就好像各个角色,人物关系。而操作函数就是各种故事场景。有了它们看上去终于像是一个小说的脚本了。现在才开始使用你学的编程语言来把这个脚本写出来。

讲完了「理」,再来讲「术」。

既然知道了你需要依次点开这几个技能点,那就看看你卡在了哪一步上。最简单的方法就是找四门课的教程,做教材里的中高难度的习题。看看哪一门课的习题做不出来。我猜你是卡在了数据结构或者数值分析上。大概率是数据结构。

想提高数据结构的能力,刷leetcode

在搞定了数据结构后,要提高数值分析,就是试著实现教科书上的演算法。就像其他答主说的「唯熟尔」。你可以认为数值分析是在计算数学方向上特异化了数据结构和演算法。

最后讲「道」

自己撸一个cfd代码,既不是成为优秀cfd研究人员的必要条件,也不是充分条件。

优秀的cfd研究人员一定有能力撸一个,但不一定真的去撸一个。因为投资回报率太低。所以不是必要条件。

计算是一种研究方法,对于流体力学的理解也是cfd研究人员不可或缺的。所以不是充分条件。

最后,多学学外语,锻炼身体保护视力颈椎和腱鞘,有时间刷刷leetcode,读点金融IT或者机器学习啥的。这些事情的投资回报率都比自己撸一个cfd代码高。


2019,9,24更新,经过一暑假用matlab写界面,数模也用的matlab,我发现它真的是画图奇才。小波分析,希尔伯特变换都很方便!同学们用起来!

――――――――

写代码这种事,我觉得首先是数学建模你得及其清晰,说白话了,你的公式得很清楚。

其次才是代码本身,首先你要搞清楚,在cfd,代码不是目的,是工具,但同时工欲善其事,必先利其器。我是个脸皮极厚的人,我在修自己课程同时去计算机那边蹭完了数据结构,演算法,计算机网路等等。包括我们自己课程标准的课程,流体力学里的数值计算,高性能计算里面所有大作业都自己一个人刚下来,过程是痛苦的,但是计算机是一个实操性很强的学科,看书是没有用的,就不如每天都敲。我认识的计算机老码农甚至和我说,你要是真吃不透一套码然后你又觉得好,你就背。我那老伙计还有句「写代码就像写文章,你肚子里得有货,然后你得天天写」。

第三,代码可能在我们这用的有面向过程(fortran/c)面向对象(cpp)当然还有解释语言(python)等等。

这几个语言各有各的活法,fortran面向过程,当然一般计算机大佬你和他们讨论fortran他们都「这玩意儿老掉牙了我不会」,(如果你想转码转行这个语言肯定不推荐 )这个要学安利一本教材fortran95,我们课题组都看这个起步的,然后看书没用啊得对著IDE天天敲(这里不知道你喜欢什么IDE,如果是fortran和cpp或者c,安利一波codeblocks)

要是面向对象的cpp呢,比如我们常用的openfoam就是这个写的,那首先轮子哥那本教材敲一遍语法什么的绝对烂熟于心了。但是我当时啃那个大厚本子没兴趣,字又小,我只把它当工具书忘记了东西去查查看。cpp基本功我应该还是在数据结构这些计算机课程的每周一次大作业里摸爬滚打的。所以多敲好代码最后真的就能敲好代码。btw,我还修过java,语言规则比cpp清楚多了。当然做计算cpp应该会更好,java做可视化本身有很多包可以用。如果你对cpp的面向对象糊里糊涂,我建议你看一下别的面向对象语言你就豁然开朗啦,比如java的对象注册数据结构就被用在了openfoam里,他们不过用的是cpp实现的。

好了到python了,这是个脚本语言。如果你用openfoam,它内置了很多脚本,不过由于是Linux系统是shell脚本。那么我觉得可以一起学习的,在作数据后处理的时候,python比其他真的好用。当然它的语法规则也是很清楚,你对著图灵系列的python书多敲敲就行然后书后习题可以挑挑做做看。python里面的字典这个数据型就被openfoam用cpp实现的。我写python用的是pycharm社区版这个IDE。

matlab这个,hmmmm,我笔记本一直带不动我就不赘述了,也是个包很多专用来搞计算的,等我换个笔记本我再来学吧……

最后的最后,代码风格,我之前就被几个老码农无数次批代码风格稀烂。头痛欲裂之下,我走上了github开源之路。就自己平时写的大作业我就放上去然后对著比如Google的cpp代码规范慢慢改直到我找的帮忙我看代码的人不再骂我为止。

话说回来,代码规范挺重要的,比如openfoam也有它的规范,比如抽象模板类一般首字母大写,要区分成员变数和其他变数等等。就你可以少些几行注释啊。


建议先花几个月,每天花一点点时间,实现数值分析、数值代数的上机习题,再进行CFD编程。

大部分工程系半路出家,基本功没到位,操之过急只会陷入调包的陷阱。


写邀。

我一直觉得,学习计算机科学中一个演算法的时候,证明是否掌握的最好方法就是实现出来。


前cfd演算法研究人员。

MATLAB和Python写著玩处理一点简单的东西还行,做cfd可能还是不能完全指望它们。我一直是Fortran写的比较多,c++也有。偶尔用MATLAB测试一点小东西。

从我个人的经历来说,最开始零基础的我是从学习前辈的Fortran和c++代码并结合数学推导,一步步理解。我们组里的代码,在前后处理部分基本上没有什么差异,彻底读明白之后基本以后就不怕了。

而具体演算法部分,则需要和数学结合著来写。从前辈的代码里也可以学到很多基本的操作。

我大概是学习了月余,才从零开始写出了第一个简单的可以运行的程序。这个过程是很枯燥的,总的来说,多注释代码,多画图,联系网格和数学公式,对于理解和学习代码很有帮助。


这种情况只有多看多练,因为写程序不是理论性的,基本靠经验。


首先是学一门语言,c和fortran都可以。然后亲自实现演算法。从简到难,CFD做研究编程不难。但编大型程序语言计算机方面的基础。


编程不是一个挑战 关键你得多练 编程的排错 如果你用的是纯c是个挑战 实际上真的挑战是跨进程逻辑和并行排错 编程其实主要是思想


CFD编程应该以C++和Fortran为主,Python这种效率不行吧。你可以先用C++写最简单的一维求解器,然后再向二维三维扩展。每个课题组应该都有祖传代码吧,可以问师兄要一份自己做参考。


这个事情不要太为难自己,国家队/各大学阀都无能为力。可以看开源代码如何写的,模仿他们的也是不错的选择,慢慢来吧


推荐阅读:
相关文章