GAMES 图形学系列笔记(三十六)

GAMES201:高级物理引擎实战指南2020 - P1:Lecture 1 课程介绍 - GAMES-Webinar - BV1ZK411H7Hc

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大家好,我是胡渊明,然后我在mit读书,非常高兴有这么多同学,一起来看我们的这个高级物理引擎实战,2020这个课呢整个是基于太极编程语言的,呃内容呢就是关于怎么写一物定情,我们非常注重这个物理型的实战。

所以呃每位同学呢,我们希望每位同学都能在这个课上,写一点自己的代码,因为你写的代码和听我讲数学公式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你的感觉是不一样,你会很有成就感,这个课呢,当然我说的目标就是自己动手打造一个呃,影视级的物理引擎,适合人群0~99岁的计算机图形学爱好者,如果大家有一点高等数学啊。

或者python或者任何一门编程语言的预备知识的话,嗯那就最好不过了,我们课程安排是每周一,北京时间晚上八点半到九点半,然后一共十节课,这个一个小时的课程有可能我们会往后延长。

有可能是比如说八点半到十点,这个根据大家的反馈,然后我这边是早上八点半到九点半,这个时候我们正好是12个小时时差,所以一般都是把am换成pm,pm或者m就可以算波士顿和美国和北京的时间。

课程内容我就不多说了,后面我们会具体再讲一讲,好那么我们先开门见山定义一下什么叫物理琴,我们在wikp件上可以看到这个定义,屋顶擎是一个计算机软件,它提供对于一个物理系统的近似的模拟。

比如说钢铁缸体物理的动力动力学啊,和这个软体动力学啊,以及流体动力学嗯,主要的application呢是在computer graphics里面,然后游戏啊和电影,那么这可能非常长的,其实一句话说的。

就是在你的电脑里面模拟这个世界,这个是呃,我想这大家应该有很多同学想想过做这个事情,我觉得还是一个很有意思的事情,我小时候就很想,怎么在电脑里面模拟一个世界出来,然后,这个除了,刚才说到这些应用。

它还可以在呃工业软件里面有很多应用对吧,你现在你去做一个模模型,你要做他的这个应力分析,你可能先在电脑里面算一算,看看它呃,做出来以后应力分析可能会是什么样,然后这样你就不用真的把它做出来,然后试一试。

发现诶这个不行,重做一个,这个就这种迭代过程,可以完全用在计算机里面进行,然后还有一个很很重要的应用呢,就是电影里面的视觉特效,这个是嗯现在电影里面特别是动画电影。

基本上每个电影里面可能有非常非常多的镜头,都是用物理效果给它模拟出来的,第三个能应用的就是这个虚拟现实,增强现实,这个应该不用多说,如果你在vr里面有一个基于物质世界的话,那你的,沉浸感会增强很多。

因为你可以和这个世界交互了吗,并且这个世界,这个虚拟世界里面的物理规律,和现实世界里的物理规律它是一致的,所以你就可以有更好的vr体验,当然现在很多人用物理琴来训练机器人,比如说无人驾驶。

我搞一个街道的物理引擎,这样车就可以在虚拟世界里面开,不用到真实世界里面冒着一些呃交通事,产生交通事故的危险,当然了,这个大家可能最关心的物理引擎的用处,还是在游戏里面,那么我今天就仔细想一下。

讲一讲游戏。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那我很小的时候就玩过很多义务的游戏啊,基本上他们构成了我童年的很大的一部分,就有一个我印象非常深刻的叫做incredible machine,这个时候叫中文叫做不可思议的机器啊。

这是一个问他这个游戏是这样的,你可以,在游戏里面摆入各种各样神奇的道具,比如说这个你可以有一个球,然后你可以有火箭,有杠杆,然后这些都会根据物理规律来运动,那个时候呃,其实这个游戏里面有一个问题。

就是他这个球它是不会转动,它这个球只会以各种形式平移,当然我是20年以后重新到网上找他,视频出来的时候,我才发现原来居然有这个问题,我之前小时候玩的时候,完全没有意识到有这个问题。

可以看到大家对随着时间推移,对物理项目的追求真的是水涨船高,小时候玩一个这个我觉得已经很厉害了,然后后面有更厉害的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大概可能这个大学很多同学都玩过,我记得我那个时候是那个时候,我可能上初中或者可能初中的时候,那个时候非常流行,ipad,就是最早的第一代的ipad,ipad上面它提供了一个触摸屏。

这个触摸屏它可以多点触控,然后嗯一个很经典的游戏啊,就是这个愤怒的小鸟对吧,这个愤怒小鸟,你可以通过拖拽这个你有多趣的弹弓,然后这个弹弓打出去呢,这个小鸟就撞到游戏里面的各种障碍物,障碍物。

有的时候碰到遇到碰撞,这边我就没有找到一个视频,但是这个截图应该我相信很多同学都玩过这个,我觉得还是很有意思的小说,我花了很多时间玩这个啊,另外一个稍微更加呃可定制一点的是一,这个是一个纯的物理引擎。

它不是一个游戏,它就可以你自己在里面放各种东西,放点什么齿轮啊,放点什么水啊,然后滑轮啊,包括棱镜啊什么的,你就可以这个软件叫放,你可以在里面嗯创建一个物理世界,然后去看他怎么模拟。

我小时候经常玩这个东西,这个感觉有一段时间好像小上小学,那个时候可能上上小学09年的时候嗯,可能是小学或者初中吧,然后那个时候特别喜欢玩这个,大概每天一放学就玩这个东西,15年的时候呢。

又有一个很有意思的游戏,这个叫besiege,这个游戏有什么特点呢,就是说你可以自己把各种各样的模块,把它组装成一个你的工程武器,你带着这个工程武器,你就可以去去攻打各种各样的城池什么的。

这个我自己没玩,这个是我本科的时候看我呃,我室友他玩的,然后感觉非常有意思,就可以,我看他造的各种什么飞艇啊,或者什么呃工程车啊什么的,我觉得还挺有意思的,不知道我一个同学现在有没有在看这个视频。

这个我觉得很有意思,我小时候就很想造一个这样的游戏,但是后来毕竟没有机会去造,我觉得这个造出来还是很有意思啊,我最近大概是去年暑假,我玩了一下这个塞尔达传说,这游戏里面有很多物理效果,有很多谜题。

你需要用物理型去啊去去解决,这个是这个物理型的一个bug,你如果把三个箱子堆在一起,你就可以通过拉最后一个箱子的方式,让自己朝前移动,唉但这个不是很物理啊,嗯最近应该说我3月份的时候玩了一下这个。

ori今年最新的这个ai,然后我觉得还是非常不错,这个游戏里面几乎所有的东西都是可以动的,你踩到地上地会往下陷,然后啊你和可以和这个游戏里面,各种各样的东西去交互,然后我3月份玩的时候。

因为我是比较早期的玩家,然后有各种bug,我觉得这个效果还是非常好的,然后他不能再放这个水,再放摄影,大家都要去玩游戏,也不来上课,刚才讲了一下这个各种嗯,可以说是过去二三十年整个物理型技术里面。

我自己玩过的一些游戏吧,那么下面我来讲我讲讲自己的物理引擎的故事,这个从大概初二开始到不是3年级,这个居然11 2年过去了,我还在做,和小时候喜欢做的是一样的东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

很有意思,来看一下,这个是我09年的时候写的第一个物理引擎,这个其实非常简单,就是一个弹簧质点系统,那个时候那个时候我对09年我我应该是初中,我现在想起来了,因为这个这个我确定是初中的时候写的。

你可以看到当时这个可能用一台不太好的笔记,本,分辨率实在是非常低。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以你可以看到这个还是一个双核的笔记本,它这个是一个,你可以创建很多这个弹簧质点系统,然后呃视频我没有留了,我只有一些截图,这个代码我也找不到了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

后面有一些有视频的啊,这个是11年的时候,那个时候我应该上高中了,那个时候学了1年刚提动力学,然后写了一个钢铁的物理性,应该也是受到愤怒小鸟的影响,因为当时玩这个游戏。

就想这游戏里面这个物理效果是怎么实现,然后我就自己写了一个那这个代码代码呃,链接上面是有的,不过我觉得一个有意思的就是。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个代码到现在还能跑,我可以跑一跑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

啊,我来跑一跑这个物理引擎,这个最早我是在windows上面写的,那个时候没有买这个macbook pro,然后后来我把它push到mac上面,还是挺有意思的,可以加各种各样的几何体。

这个有一些参数可以调,然后调了以后,比如说我现在可以把摩擦关掉,大家可以看一看效果是什么样的,就滑滑走了,然后我再把它拆下来,我还可以把重力调成负的是吧,我看看啊,可以,嗯你可以创建各种几何体。

我记得还有个功能可以画任意集合体啊,对,他会做一个三角形的translation,然后把它用三角形表示出来,再看看,嗯能不能画一个齿轮,我记得有一个功能可以画齿轮才好,哇,这个快捷键我十几年过去。

我居然还记得,真有意思,我们把它,嗯这个理论上这个齿轮是可以驱动的,但是我已经忘了怎么去拖它啊,可以拖可以拖,对我再看看我自己有一些其他的场景,这个是一个康美,这部分叫做牛顿摆,这个我记得当时。

物理老师经常喜欢用这个东西来做一个演示,我我可以尝试一下,你如果放一个,你看到这边弹起来是六个的,左右边一定会弹起来,六个左边一定弹起来六个,这个我记得当时上物理课的时候,盯着东西看了好久。

下面是个多米诺骨牌,来哎哟,这,还有一些别的电报啊,这个是一坨弹簧,你可以看,我可以拉近一点,就我小时候玩过一个玩具,叫做好像叫做什么机灵鬼啊,就是一坨一些弹簧,你可以两个手,他可以从左手跑到右手。

右手跑到左手,嗯应该就这些demo,所以这个代码已经年久失修了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看看最后一次什么时候改的,他最后一次是8年前,8年前我把它扩展到mac os x上面是吧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还有这个2012年8月26号,时光飞逝。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok然后下一位啊,这个是我14年,我应该是大二,大二的时候写的一个基于物理引擎的游戏。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个还是能跑,我看看跑一跑看看。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok嗯这个是这个物理性,不是我自己写的,这个是用的box stud,当时我记得很喜欢玩一个游戏,叫做纪念碑谷,然后这个画风就抄了纪念碑谷啊,这个你是你可以通过w s a d去控制,这个能转的这个小人。

然后你可以让他去驱动这个齿轮什么的,哎呦这靠的太近了,有的时候会和齿轮卡住嗯,转这个齿轮的时候,这个右边这个树会长出来,上面这个齿轮好像是控制光影,看看,嗯我一开始想做一个完整的游戏。

后来因为没时间做了一半就放弃,做了一个最小化的demo,这个大家可以自己去这个网址去玩一玩,还是挺有意思的,这个看起来是三维,但它其实是很多分层的二维物理,你看到这个这个块,它虽然浮在天上。

但它其实是会还是一层一层之间是有碰到颜色,但层一层之间是没有的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok赶紧把它关了,这个很好gpu啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个是我大概16年的时候。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

写了另外一个游戏的模拟,这个也在网页上可以放这,大家呃可以我结束以后会把size share在网上,大家可以直接点进去玩一玩,你可以调各种server参数,你可有的时候so参数不对,他就不work。

你看这个jiobe iteration,如果不进行,他就肯定不行,然后这个flip的话,你可以在里面选择,那这些复杂概念我们后面都会介绍,所以大家暂时但是听不明白的话呢,不用担心,你可以调分辨率。

我记得我当时好像你现在随便找一个ava的,少好一点,gpu跑512x512,实时是没有问题,但我这个笔记本实在太烂了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

没有办法,你可能有同学说这个风扇转起来可能非常吵,我就先把它关了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以这个是16年的时候啊,这个是一个17年的时候写的一个烟的模拟,哎呦怎么这么卡,哈哈不好意思,这个笔记本实在是不太行,啊这可能放的不是很流畅,我试试再放一遍行不行,啊看来这个笔记本已经放弃了。

anyway啊,这个当然,这个我后来跟做烟雾模拟的这个张星星前辈。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请教了一下,然后他说这个太黏了,效果不是很好啊,我就不过多展示了啊,这个是我呃,这个是我的第一篇cup paper,然后我们是用m p m做了各种切割的模拟,然后它实现了固液。

这个固体和液体的显示的耦合,然后切割是这个耦合的一个副作用,我们可以切各种切香蕉,切这个兔子,这个叫奶酪嗯,你可以切沙子或者叫搅拌沙子,那这个算这个文章里面呢,我还提出了一种基于移动最小二乘。

kl的一个新的物质点法,它会比之前c杠c2 的物质点法要快两倍,还是基于2016年的蒋老师的一篇,叫iphone particle excel paper去进行的一个算法上的精简。

这样使得它计算的时候工作量会小一半,有同学问这个渲染时间和粒子的数目,这个我可以说一说,基本上这边所有的都不是实不是实时的,这个paper里面基本上没有实施的联盟,然后切你像这个切兔子或者切奶酪。

这个基本上都是100万个到,300万~400万个例子,而这个右下角这个角沙子,这个大概有我记得有三三百50万个例子,我们当时模拟它可能得等等,上一天还是挺费时间的,但是现在呃。

pm这个算法就是它的性能逐渐的也在提升,所以逐渐的很多实时的应用名额应该也会出现,这个是一个更大规模的例子,这个是西瓜fisher,2018年,我们做了一个,在一台机器上面减10亿个voxo的fm。

然后用fm做完fm以后,我们有sensitive sensitivity analice,然后可以做top your puzation,这些概念我后面都会提到这边嗯。

大家只要记住这个boxer数目非常多就行了,干嘛网上也有,然后大家可以自己下来下下来跑一跑,这个跑的时间就非常长了,这个我记得这个demo,可能跑了得有一个星期,我记得嗯中间还挂了一次,我还重启了。

我对这个事情印象特别深刻,所以性能是非常重要的,在物理模拟里面,然后最近一个东西我最近开始搞的是可威模拟,那这个东西其实很早以前也有,只不过我们最近把它流程搞简化了一遍,什么叫可微模拟呢,呃可以模拟。

就是说这个视频可能不是很流畅。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我尽量让它放的流畅一点啊,你问这笔记本已经弃掉了,现在已经非常卡了,可能是因为刚才跑的那个gpu的程序嗯,回模拟,就是说嗯,我们正常的模拟就是给你一个初始的状况,然后让你预测。

比如说十秒钟以后这个系统是什么样的,然后呢可微博你是反过来就说嗯,我希望去求出初始状况的一个扰动,对于结果影响是什么样的,然后这个其实就是要求一个梯度对吧,当你有梯度的时候。

你就可以对初始状况进行各种各样的优化,比如说这个地方,我们就在求一个初始的水面的高度上,使得经过512格time step以后,可以得到一个太极的pattern,就可能现在解释有点抽象。

我们后面会继续讲,那我得看一下这个到底是怎么回事,为什么这么卡,嗯看起来是直播软件卡,那我就没办法了,如果别的卡,我还能关了,直播软件关了,我就不用直播了,那我们只能忍一忍。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就到了今年了,刚才讲了过去10年的故事,那现在我在mit读博士,现在第3年了,然后我还是在做数据类型,但是我花很多时间去写编译器,为什么呢,因为我发现如果你没有一个好的编程语言,没有一个好的编译器的。

你要写高性能simulation是非常非常难的,就是非常非常费时间,所以我就重造了一个编程语言,这样大家就可以更容易地写自己的simulator,那么现在基本上可以说有一半的时间。

都在做这个太极编程语言,当然这个里面有非常非常多的贡献,是太极社区的同学们一起帮忙做的,真的大家非常不容易,我觉得每天早上一起来就能看到github上,github上面好多的衣服,每天跟大家一起来嘛。

就跟开网打网游下副本一样,就解决一个个很难修的bug,进行各种各样的设计决策,真的非常有意思,呃当然我最近也开了这么个课,然后主要是想跟大家分享一下,怎么样去写屋顶晴比较嗯比较有意思。

当然也做做这个直播,带货带一带这个太极编程语言,希望大家都能尝试一下这个新东西,那么我们接下来讲一讲这门课,我们会注意我们会注意力集中在什么,哪些关键词上面,我们会简单讲讲各种各样的离散化。

那这部分数学比较involved,所以呃可能也不会讲的特别深,更多的呢因为我自己主要是做计算机方面的,所以我会更多讲一讲,你从一个程序员的角度,怎么去直观地理解各种各样的离散化。

我们会讲怎么样写有效率的求解器,比如说嗯现在你要写一个free sober,很很长的时间,很可能就是花在这个linear systems of上面。

不同的linear systems over它的性能有天壤之别,后面我们会继续呃,详细介绍这些pregnitioner,我们会讲讲怎么样去提高呃生产力,怎么样用比较短的代码实现一个高效的物理题。

你别看这个短代码啊,听起来好像是一个非常糟糕的metric,好像这个代码行数用代码行数是measure,一个软件呃,是非常糟糕的一个metric,但是你仔细想想,有别的更好的metric吗。

其实你很难想到比这个代码行数更好的metric,这也是为什么我喜欢用这种metric来证明呃,一个代码可以用很少代码能写出来,当然我们也很在意性能,刚才提到很多模拟的我们都要等上一天的时间。

然后量的话呢,其实你如果要再去做迭代的话,那就非常非常费时间了,我们也会简单介绍一下硬件的题结构,因为你如果要写高性能sover的话,你得去了解一下你的硬件是什么样的,如果你不了解硬件呢。

那你就很难把它全部利用起来,我们也会讲讲各种各样的复杂的数据结构,然后但是太极让这个数据结构的使用,变得更加的简单了,这个后面我们会详细介绍,我们也会讲讲怎么样去做复杂的并行,因为现在并行硬件大行其道。

cpu和gpu如果算它吞吐量的话,那真的是天壤之别,一般能插上一个数量级,然后这边展示的是saber 2000呃,2020年的一篇比较新的saber paper。

这个paper的结果非常非常impressive,他们可以用四个gpu,然后模拟呃,应该是1亿个particle,这个在之前是前所未有的,大家可以呃,有兴趣的同学可以去读一读这个paper。

然后我们会最后我们会讲讲,怎么去simulator的导数,导数求出来呢,你就可以做很多有意思的事情,比如说我们这边还有两个机器人,都是软体机器人,上面的是一个嗯,上面机器人他有四块肌肉,就是他有两条腿。

每每条腿有两两半,然后左边一半,右边一半,每一半可以伸缩,或者可以叫叫叫什么,可以啊,变长或者变短,就是相相当于你的肌肉嘛,你可以肌肉可以收缩或者舒张,那下面一个呢是一个弹簧质点的机器人。

上面这个是一个m p m机器人,好那么我们这个第一讲的上半部分就结束了,我们来下面呢我们介绍一下太极编程语言,因为这个是一个大家都要用上的工具,嗯好,那么现在啊这个slides。

我在整个课程期间会不断的更新,因为我们今天只能讲一讲最简单最简单的内容,然后后面我们会逐渐的加入,太极里面的一些比较复杂的feature,这些slides呢都会,课程结束以后都会在网上有的。

所以大家不用担心,如果说有任何size里面没有介绍的东西了,大家可以去看泰迪的文档,现在泰迪的文档在大家努力下呃,英文文档和中文档应该都是比较可读的,特别是中文档真的非常不容易。

就是呃基本上就以大家以迅雷不及,掩耳盗铃儿响,叮当仁不让之势,就把这个中文中文档给他全部翻译好了,真的太不容易了,呃当然很多feature我今天讲到的,并不是我自己一个人写的。

很多feature是我们社区一起写的,然后我当然也不是唯一的developer,那么什么是太极呢,太极是一个高性能的这个领域特定语言,它在呃嵌入在python里面。

然后所以它的语法和python非常非常的像,然后你如果会python,那你基本上很快你就可以嗯,你就可以怎么说呢,学习拍这个太极语言怎么用,他这个语言专门是为了计算机图形学的应用,来设计的。

我们在设计的时候,非常非常注重生产力和可疑之心,这两个东西,以前在计算机图形学里面是呃非常难以做到的,我说的这个生产力,不是说你用游戏引擎做游戏的这个生产力,我说的是对于一个想研究图形学算法的人。

去写一个图形学算法的生产力,我们也很注重possibility这门课呢,我们建议大家都使用太极编程语言,因为太极程序有什么好处,你在一台机器上写的太极程序,复制粘贴一下到另外一台机器。

只要一台机器装了台机,基本上都是能跑的,这个就和你和open gl呃,和你用其他的像ka写的程序就完全不一样,因为你很容易,如果你不用太紧,你会各种各样的依赖,你就为了让一个画一个三角形。

你可能要装三四个包,就非常非常麻烦,泰迪呢是面向对象的,然后它是自自动并行,并且kero是mega kernel,这个和深度学习里面的那种呃,cosmeability比较弱的kernel是不一样的。

我们还有一些比较好的系数系数,数据结构以及可谓编程的知识,这个我们就后面再介绍了,ok那今天其实就讲几个非常简单的内容,怎么安装,怎么定义数据,怎么做计算,然后怎么进行调试,我们先看看怎么安装。

那么如果你用python 3。6,3。7或者3。8,你就可以直接用pip去装一下太极,大家要注意一下呃,我之前闲聊的时候也说过,就是说国内语言有的时候它有一点延迟,所以有的时候,比如说官方语言已经0。

6。7了,然后管理员可能还是0。6,然后就会有一点延迟,然后呃就会导致因为太极可能不是最新的版本,这个我自己没有去实践过,但是之前知乎上面有很多人跟我说这个事情,就是说大家装个手要确认一下版本嗯。

然后三个主流的操作系统我们都是支持的,太极程序呢也可以记在cpu上面装,也可以先记在cpu上面运,行,在gpu上面运行gpu我们支持q a,然后open gl和apple metal。

如果你有一些神奇的配置,比如说你的cpu是arm,或者你非要用python 3。9以上,那也没办法,那你就得build from scratch,你底下太极的源代码下来装吧。

但如果我相信用python 3。9的同学是比较少的,最最新的pyth好了,已经30了,我记得5月25日的时候呃,好像3。10已经出现了,但是大部分同学应该都是3。6或者3。7,3。8可能都是相对少数。

但是我们也是支持3。8的,那么初始化太极这个非常重要啊,每当你在运行一个太极程序的时候,总是呃请总是调用一下t i n it就是initialize。

before you do any touch operations for example u ti。n点,你可以在这个里面specify这个指定你的后端,比如说我们这边用的是tr减q的呃。

这个是arc,这个是一个最最最常用的参数,因为呃指定了这个2k以后呢,你就可以去呃选择到底在什么硬件上面跑,可以是x a x a,可以是x six four,可以是arm,可以是kda。

可以是open gl,可以是metal,你可以随意选择一个掰开,当然你系统得支持了,你如果系统不支持,那我们也没有办法,建议大家使用ti。cpu或者ti。gpu,为什么呢,因为呃你如果呃用这个tr。

x sixty four,那他可能你如果在arm上面就跑不了了,你用cpu它就会自动检测你cpu是什么样子的,如果gpu呢,它会自动检测你的gpu,它会逐渐的先去try coda。

然后try metal,然后try open gl,if nothing啊,如果没有任何事被检测到呢,太极就会返回到cpu上面去运行,当然这个ti点因为它有各种各样别的呃参数,这个我们后面会介绍。

那么下面我们来介绍一个太极里面,最最最基本的概念叫做tensor,就是说呃sorry啊,就是data data,就是说呃你运行一个程序,你总得有一点有一些数组啊之类的东西,来存这个程序的状态对吧。

那么太极里面支持的数据类型,其实呃和c非常像,他有这个八位的,16位,32位,64位的整形,然后里面呃,整形里面又分为带符号的和不带符号的,然后还有,浮点数类型有32位和64位,浮点数类型。

一般来说我们自己一般来说,我非常喜欢用32位的类型,带符号的整形和30位浮点数类型呃,现在我们还暂时不支持不练类型,我们不支持to false这种类型,所以我们的所有的比较返回值。

都是在要用ink thirty to,用这个整形来存储的,当然这个并不是所有的后端,都支持所有的数据类型,因为毕竟比如说啊open gl里面,他可能不支持64位的浮点数。

有些你可能需要一些excel才能用呃,或者不支持64位整形,然后呃所以这个我们文档里面有一个表,就详细写了,每一个后端支持什么样的数据类型,大家可以看一看文档,那接下来我们介绍啊。

数据里面的最重要的一个概念叫做tensor,我同学的bat是什么意思,bcat就是,怎么解释呢,就是用来执行你的程序的硬件,就是说嗯你可以在程序,可以在cpu上面运行的时候。

cpu就是你的bad end,如果你在gpu上面运行了,那么gpu就是你的backend,但有同学说对这个是一个编译器里的概念,所以可能我刚才讲的不是特别清楚,就是我sim的bat是什么,大家都知道。

但是呃其实它意义不是特别明确,这个是一个非常经常被abused被滥用的一个词,还有很多很多的意思,这里呢就表示执行计算硬件,ok那么下面我们来讲讲这个tensor,tensor就是张亮。

张亮其实是一个fancy的名字,一般来说呃,你可以就可以认为张亮是高维数组对吧,但是它在物理里面有一些什么协变张量,为立立立变张量啊,这些它是有别的物理,但是在太极里面他的张量没有物理。

它就是一个高危数组,它的这个数组的维度可以是零维,可以是一维,可以是二维,可以是三维,你也可以认为零维的张量呢就是一个标量,一维的张量呢是一个向量,然后三位的张二维的张量是一个矩阵啊。

但是这边就有一个地方可能比较computing了,因为你的张量里面的每一个元素,它又可以是一个标量呃,向量或者矩阵,所以我们从来不说,我们在太极里面嗯,会把张量和矩阵给他严格的区分开来。

然后虽然在数学上面呢,你的举证有的时候会被认为是,比如说tod tensor,但是在太极里面,tensor和matrix是两个完全不一样的概念,这个大家一定要注意区分,因为如果不注意区分了。

后面会可能会非常confused,然后你的tensor element可以是scale factor或者matrix,那么你要去访问这个tensor admin的时候呢。

就永远用这种ai j k的语法来去访问它,太极里面不支持pointer,pointer,有的时候是万恶之源,因为你用了pointer呃,编译器就很难优化你的程序。

以及你会容易trigger一些undefined,behavior,这个你程序就为了以莫名其妙的原因挂掉对吧,然后a i j k呢可能会给你返回一个scaler。

也可能会返回一个vector或者一个matrix,然后你可能还需要再用呃pq来去访问,返回的matrix里面的真正的一个数啊,就是这个有一些confusing,后面我们会给一个例子来介绍一下啊。

这边就是一个例子,然后我们在这个例子里面呢,我们定义了几个四个tensor,分别是a b c和loss,然后a呢是一个标量张量啊,这个听起来可能有点confusing,就是说啊它是一个张量。

然后这个张量呢有42x63个元素,每一个元素是一个标量,那b呢是一个向量的张量,这个像这个,b这个里面它是一个你可以看到它是ti bor,然后第一个是个三三,这个是你这个向量有多少个元素向量。

这个里面这个其实是一个3d的tensor,所以3d的vector,所以我放了三这边,然后后面又有一个shape,这个shape是这个tensor shape,所以你可以看到啊,b这个东西。

它是一个四个3d vector组成的一个张量,ok这个有点confusing,所以我得花多一点时间在这,然后你可以我们再看c c里面呢,你看它是ti。matrix 22对吧,那它是一个2x2的。

它的这个张量的元素是一个2x2的矩阵,后面又有一个shape,这个shape是tensor的sha,那这个地方其实就是一个3x5的tensor,这个tensor 3乘五的tensor里面。

每一个element是一个22的矩阵,这边应该是现在大家应该清楚了,然后这个loss我们来看一下,这个loss是一个比较神奇的东西,你看它的shape是空对吧,它是一个shift里面的东西是张量的维度。

那么shift是空的,说明他是一个0d的张量,0b的张量是个什么概念,0d的张量就是只有一个元素的张量,这个元素是什么呢,这个用的是加点y对吧,说明它是一个呃标量,ok那么我们下面呢就可以在太极里面。

我们可以去,给这个张量里的元素赋值,比如说我们可以让a的第三行,第四个元素给它设置成一,然后我们可以把它print出来,然后呢我们也可以给一个向量一次,给它赋一个list,这样可以把它这个向量里面的值。

设置成这个list里面的值,这边要注意一下嗯,大家可能会想直接print b的第零个元素,第零个元素是什么,是一个向量对吧,呃你可以可能会想print b0 ,但这个我们暂时还不支持。

后面我们很快就会支持这个社区的同学,正在非常辛苦的在work on这个东西,然后最后一个loss,这个地方一定要注意loss,因为它是一个林地的张量,所以你访问他的时候,我们必须要用下标,那怎么办呢。

我们会给它一个下标,叫做n,那样的话就是说他没有下标,那他就是呃领地的张量,这边为什么不能写loss等于三,loss等于三,你就真的把loss的值设成三了啊,那你这个loss以后就是三。

它就不再是一个张量,这个是python语法的限制,好后面大家程序写多了,就会就会知道,这个地方其实设计还是不是很容易的,但是我们已经尽我们最大努力了,那我们来看一看计算。

计算里面最重要的概念就叫做kernel,然后kero有非常非常多的意思嗯,操作系统有可能浏览器,有可能各种各样的东西都有可能,太极里面的kernel是什么呢。

太极里面的kernel就是呃用来计算的那个函数,大家可以记住这个解释,就是太极里面kero就是用来计算的函数,然后呢太极刚才我讲的其实全部都是python的语法,下面我们来讲一讲这个太极的语法。

泰迪kero里面自己有一个语言,这个语言非常和python非常非常像,唯一的区别是什么呢,唯一系列是这个语言是会被justin time,就这个即时编译的,然后太极自带一个编译器。

把呃kernel里面语言编译成高性能的kero,然后这样就能摆脱python这个run,运行很慢的这个问题,它是静态类型的,然后呃lexically scoped就是说它不像python那样。

你在他python的scope是以function为单位对吧,但是太极的课程里面,scope更紧一点,它是以block为单位,然后这个kernel会被自动的并行,并且在某些情况下是可微分的。

kernel必须被太极的克隆,你如果要让他知道泰迪知道这个是kero,你必须给这个函数前面加一个decorator,就是ti。kernel,那有了这个decorator以后呢。

太极的编译器就会把这个函数的巴黎拿到,然后进行编译,编译以后呢,把这个跑的很慢的函数,替换成一个跑的很快的并行,cpu或者gpu上的一个高性能的函数,如果你想给kernel传一些参数的话。

那请一定记得给他呃,加加上这个参数类型,因为毕竟太极是一个强类型的东西,然后,我们这边有两个例子,第一个例子是hello world,那其实你可以看到它和python其实非常非常想。

然后但是为了让他和python非常非常像,我们花了很多精力去让他和python非常非常像,因为要不然大家学起来这个负担就比较高了,对吧,你重新学习一门新的编程语言,跟这个拍照要花很多时间。

但现在基本上你会排成,那你上来就可以写太记,这个我觉得是一个非常好的设计取舍,如果你要让kero有返回值呢,那请一定要记得给它的返回值,也加上一个数据类型的一个hint。

那么比如说这个calculate这个函数,它返回的是一个三刷微整形对吧,那你要记得给你define calculate的时候,要给它有一个返回值的类型,那函数刚才讲了,kero其实是函数。

那函数的方式也是函数,它们有什么区别呢,呃其实区别非常简单,就是说嗯function可以被太极的function,可以被太极克中调用,但是太极的function不能够被python调用。

这个后面我会讲到scope的区别,但是呃这边简单的一点概念,就是说你可以直接调用太极的kernel,你在python里面可以直接调用太极kernel,但是呢呃在python里面不能直接调用太极的方式。

但是kl里面可以调用function,function里面也可以调用其他的方式啊,这个大家可以通过写代码去仔细体会,它到底是个什么行为,当然这边也需要一个decorator去指定嗯。

他的呃具体的函数的类型,当然有同学说写过kila,同学可能会一下子就反应过来,function其实是device function对吧,然后colonel呢这边其实就是coda里面的global方式。

他们其实是有一个对应,但是呃这么说基本上是对的,但是有的时候一个ti。ko,他会被拆分成好几个扩大的一个global kero呃,那么我们中间还是有一些抽象的,但是你如果用呃,你如果学过枯燥的话。

那基本上确实可以认为一个是device,一个是呃global,那么太极的方式呢,它是不会被强行in in line,现在我们这个实现的稍微有点挫,强行in line,但是大部分情况下绝对是够用的。

那暂时我们因为是强行in line的这个function call,所以我们暂时还不支持递归,然后一个太极的方式呢,最多只能有一个return statement,这个大家可以仔细看文档。

看看文档里面会解释为什么会这样,大家做同学的这个程序里面,经常会用到一些常用的数学函数对吧,比如说sign cosn啊,这个ark sarcosin或者artgto,这个里面我就列出了一些常用数学函数。

这个update to是不是应该是y在前面x后面,我这边可能有个type,我讲完以后我去确认一下这个,大家不要被我感知出来三子给误导了,嗯然后像flora cell啊,然后这些都是支持的,有一些函数呢。

比如说有些特殊的,比如说t i d random,这个random是干什么呢,如果说呃你的data type是一个int的话,它会给你返回,比如说你intech to。

那它就会给你返回0~2147483647,中间的一个随机的数对吧,如果你是data type,是int 16的话,他会给你返回啊,我刚才说的应该是online,如果是online 16的话。

他会给你返回一个0~65535之间的数,如果你是flow point的话,他会给你返回一个0~1之间的浮点数,然后有一些python自带的函数,比如说,abs呃,int float啊,abs是求绝对值。

这个是python的关键字,所以就不是ti。abs,而是直接使用abs就可以,这样比较方便,符合和python尽量接近的这个原则嗯,int和float,就是说把你的这个x把这个输入给他。

convert成整数或者浮点类型,还有max或者min,max和min呢都可以像python一样支持超过两个参数,你可以x y z aw,你随便想怎么弄都可以,当然还有这个x星星y x星星管是什么。

x星y是x的y次方,这个其实也是和python保持一致,最后得到的这么个设计啊,这边还有一个要提到的是这个python里面它的除法,这个地方要注意一下,因为python 3以后把它的除法的含义给改了呃。

一般来说你这个如果你以前写c加加,或者写别的语言,a除以b,它的结果是取决于a是a和b是整形还是变形,对吧,如果你比如说a是五,b是二,然后你给他一个a一个除号b他会告诉你什么,他会告诉你二对吧。

如果你给他,如果你a是五点,b是二点,就是它如果它们都是浮点数的话,那你的这个除它会给你返回2。5,这个是这个是c里面的行为,在python里面a除以b永远会给你返回浮点数,在python里面。

如果想二怎么办呢,你有两个数,两个数法表示整数除法,你可以a啊,除以除以b,他就是自己新python 3新创建了这么个符号,我觉得还挺有意思的,所以泰迪为了保持和python的统一性。

我们也全部沿用他的行为,这样你只要会python就可以写太极,然后python还有一些其他的有意思东西,它支持这个链式,comparison这边给了一个非常极端的例子,a小于b小于等于c不等于d。

这个还是挺乱的,一般一般我们只写是a小于b啊,最多情况下我们写个a小于b小于c就到头了,但是你如果真的要写这种很复杂的training,comparisons,太极也是支持的,那么说到物理魔力。

就不得不很多时候得用上线性代数对吧,ti。matrix是呃,用来做小矩阵容,我刚才讲到tensor和mix,tensor是表示很大的高维数组,但是matrix是啊,你如果要用数组理解它。

但它只能是一个非常非常小的小数组,然后,小数组的什么概念,3x34x4,1x3,3x1,这种是属于小数的,你如果有什么10x10,那你就可以考虑一下要不要用cancer来表示的,而不是用数组表示的。

因为太极里面有些机制,你如果用一个很大的数组,它的啊太极会非常慢,但是小数组太极会非常非常快,然后呢vector它和数组本质上是一样的,唯一的区别是vector只有一列对吧。

因为vector一般会被认为叫做这个列向量嘛,它就是只有一列的一个数组啊,一个只有一列的呃,矩阵这边有一个要非常非常注意的地方,是大家要一定要小心,element wise的乘积和matrix成绩。

什么概念,就是matrix乘积呢是额数学上面的两个矩阵,a乘b它是矩阵乘法,但是element wise乘积你如果写a乘b的话,它是什么行为呢,它会把a和b对应位置的元素取出来,相乘给你一个新的矩阵。

这个大家可能得试一试,我在这说可能有点干枯无力,但是这个如果不注意的话,很容易写出bug,然后有一些常用的矩阵运算,比如说transpose inverse,transpose是求它的转置。

inverse就是求矩阵的力,但是这些所有的运算全部都不是in place,不是说a。transpose会把a本身给transpose,而是说返回给用户一个被转制过的a,然后a。

inverse就是求它的力,trace呢就是求它的trace,应该是对角线的,和中文好像是叫叫做叫做记对吧,是痕迹的g然后determinal是求它的行列式,这个行列式你可以有各种各样的数据类型。

可以是你type里面可能得费得进一个浮点数,然后normalize,normalize是求这个呃,当然这个只列向量有用啊,他是把这个向量给它呃,除以它的模长,然后再返回这边,我还漏了一个a。norm。

这个a。norm对于向量来说,会返回这个向量的呃,too lm也就是它的长度,你如果想把矩阵里面所有元素都去cast一下,你可以用a。cast,把它转化成另外一个数据类型。

我们也支持一些简单的小矩阵的呃,常规性内容操作,比如说polarity composition,然后包括s b d这些我们也是支持的,如果说你想给a里面的每一个元素都取sign,得到一个新的矩阵呢。

你可以直接把ti。sign apply到这个a上面,这个是一个ment twice这个的操作,所以所有的标量或者呃所有的标量运算符,都可以直接在矩阵上面运算,然后这个就比较方便。

那么我们接下来要讲一讲非常重要的一个东西,叫做并行for循环,太极里面呢有两种for循环,一种叫做range for loop,那么range for lop其实和python的for loop。

基本上行为没有任何区别,他就是for i in range,然后一个n之类的,这个我后面会给一个具体的例子,但是一定要非常注意的一个事情,是太极里面最外层的range for loop。

最外层的for loop会被自动运行,然后ready follow可以可以嵌套,这个后面会详细解释,然后第二种for循环叫做struck for loop,这个东西呃非常非常勇。

特别是你要做任何系数计算的时候,基本上全部都是靠这个struct flow,那它是干啥呢,它是会嗯便利稀疏张亮里面的所有的元素,刚才我讲的所有的例子全部都是稠密张亮对吧。

但是太极里面有一个非常特色的功能,叫做稀疏张量,这个后面这一讲不会提到基础上,因为它是呃挺复杂的,后面不会提到,我们看几个例子,那么第一个例子是这个feel呃,它是一个kernel对吧。

kernel是再回想一下kernel是python可以调用的,function是python不能调用的,function可以被knel调用,ok呃这个例子可能这个方式。

ko一开始可能有点computer,但是我相信大家很快就能搞清楚嗯,然后我们来看一看他这个kdle,面对外部有一个i的这个for循环对吧。

这个是一个range for for i in range 10,那它就会嗯呃并行的对09,注意这个十是不包含它是09,0123456789的所有元素,进行这个操作,它是操作会干啥呢,给它加上i。

然后呢你会看到后面有个s s,我们这边算一个0~4所有数的和,这个由于它是第二层for循环,所以它不会被自动并行,它是在每一个第一层破循环的线程里面是呃,zero执行这个串行执行的啊。

这个地方就是说只有最外层的会被并自动运行,那么我们再看看第二个这个feel three d,这个这个例子,这边有一个t i。n d range,这是一个很有意思的函数。

它是four i j k in这东西,这个还是一个range for loop对吧,但是它的这个range非常的呃特殊,它特殊在哪呢,它不是只有一个下标,它有三个下标,它是什么意思呢。

从38还剩38,j是从16,k是从09啊,当然869这个末端点都是不包含的,然后我们i j k for呃,它应这个三维的这个range,这个也是自动运行,然后它可以做一些这样的操作。

比如说x i j k等于i j i j j k,那么要注意的事情呢是呃,我们只会自动定型最外层的,最外面那个scope for循环,比如说上面这个例子four呃,这个foo这个函数它就会被自动变形。

但是你如果这个给for外面嵌套一个if,那他就不会被自动变形了,他就会被认为是一个serial的嗯,这个做过并行编程的同学应该很能理解,很容易理解为什么会这样设计。

ok我们来看一下struck for loop,那么什么是struck for loop,我们来看这么个例子,这个例子是啊,其实是这个程序是可以跑,大家可以自己去跑一跑,玩一玩哦,顺便说一下。

我不我这个size是pdf格式的,然后这个有一个问题,就是说你如果直接复制粘贴的代码,他格式上会是有点问题,他会不能正常运行,但是我会在上课以后,我会课程结束以后。

会给出里面所有能跑的例子的python的源文件,这样大家跑起来就方便一点,我们来看一看这个程序干啥呢,他先初始化对吧,大家做任何太极操作之前,记得一定要初始化,然后然后我们定义了一个tensor。

这个tensor叫pixels,这个test里面每一个element是一个32位浮点数,f32 ,32位浮点数,然后它有这个ship ship,它这个是多少呢,是640x320是吧。

n乘2n那么一个kernel ernel叫paint,这个kd里面你会发现他做了一个操作,叫做呃for i j in pixels,这是什么意思,pixel是一个tensor。

那tensor它是不是有下标啊对吧,这个tensor下标是什么,是从什么到什么呢,你看到下面我列出来是从0001020,319找101112,最后呢到300啊,639,319,就是说ig会并行的。

look over所有的下标,所有的这个tensor里面的下标,但这个是一个dance tension,那它所有的下标都是active,如果说你是sparse tensor的话。

那这个struck for loop只会loop over嗯,只会loop over,这个里面active的部分,这个后面我们会详细介绍,我看好像同学有一些问题,我看看有没有什么。

我现在可以就可以解答的,免得后面越来越confusing哦,ok我先回答几个问题,有同学问kernel可以调用kero吗,这是个很好的问题啊,kero不能调kernel嗯。

但是function可以调function,然后为什么说kernel多数情况都是串行,其实克隆大部分情况我们希望它是并行的,但是有的时候有的东西没法并行,所以它就有串行,你会开多大的,不开图这么大。

让我屏蔽一些线程,有些问题我也没有很很理解,对有同学问串行和并行是什么意思,有同学说这个串行是一个人搬完100块砖,并行是100个人搬完100块砖,这差不多吧,反正就是并行。

就是有很多个很多个worker,就很多个工作者一起同时做一个呃,高度重复性的工作,这就是为什么gpu非常适合做笔记,因为gpu的threat数目非常的多,for里面有前后依赖怎么办,这个很好。

这个是一个很有意思的问题,这个说多了都是泪,我们有一些,比如说我们看一看这个函数,如果说呃你把这个外面这个for去掉的,它这个s等于零for呃,这等于j in range five。

然后s加等于j这个东西呢它就是并行对吧,这个里面就有一个循环体,对外面的这个s的依赖,这个我们编辑器里面做了一些非常繁琐的变换,使得你感觉不到这个是一个问题,就是说大家不用担心这个问题。

但是编译器里面做了一些很头疼的事情,然后使得它可以自动处理,所以大家不用担心,ok那么接下来我们讲一讲原子操作,由于刚才说到太极里面,很多的操作都是并行的对吧,那么我们很多时候需要做原子操作。

那么在太极里面呢,这种augmented assignments,它就是自动式原子操作,然后这这边有个例子,就是说你如果要去修改并行的修改全局变量,那么就是得确认一下,你得用好原子操作。

比如说这边是一个例子,如果我们想嗯把x里面有个所有的元素求和对,那么这边有三种approach,我们看approach one是可以的,我们可以用total none,为什么用total none。

而不是用total呢,因为total是一个0d的tensor,在太极里面access tensor永远都要用括号,这个大家得呃记住,这不是一个最不是一个最理想的设计,但是是呃没有办法的办法,为什么呢。

因为你这个加等于在太极里面是原子的,加等于我们再看approach to也是ok的,pro也是好的,那这也是一个原子操作,那这个第二第二种和利润有什么区别呢,第二种这个atomic at它会返回一个值。

这个值是total none,在进行atomic at之前的值,相当于是一个呃read modify write这么一个操作,那第二种呢提供了更多的可控制性,但是没有第一种简洁。

那我们看这个approach 3,这个第三种,这个第三种就不太对了啊,第三种是呃,由于你没有用augmented assignment,你就得先把这个数读进来,然后再加的写回去,这有什么问题。

这个问题就在于你把这个数读进来,在写回去的过程中啊,别的thread可能已经也给你进行了这个途径来加,写回去的操作,你最后结果就不对了,这个是因为它不是原子操作,就会有这个data race。

data race就会有问题,这个月这个操作它就不是呃原子的,它的结果也会不对,ok那么我们接下来讲一个叫呃,太极scope和python scope的这个区别,这个是一个非常重要的概念。

就是说刚才我提到很多太极的operation,既可以在ti。ctrl t i点方式里面进行,又可以在普通的python里面进行对吧,那么这边我们就得介绍两个很是冗杂的术语,大家可能比较讨厌术语。

但是呃有这个术语以后,我们就定下来,他就指这个意思,太极scope是指什么呢,任何被ti。kernel以及ti。function修饰的函数的,函数体就叫做太极scope。

python scope是什么呢,任何呃不在太极scope里面的代码,比如说一份一份python代码,要么是太极scope,要么是python scope,ok那么有什么区别,第一点。

太极scope里面的代码会被太极的compiler编译,并且在并行设备上运行,第二点,python scope里面的代码就是普通的python代码,并且会被python interpreter去执行。

所以你可以在python scope里面do whatever,you want,你可以去,比如说你可以import pytorch,然后你在里面做一些pytorch操作。

然后把pytorch的结果把它喂给太极,然后再到太极scope里面去做太极的操作,我们可以在这个是一个在太极scope里面呃,去玩这个tensor的例子,刚才我们讲的是。

其实是在python scope里面去玩这个test,但是但是更多的时候呢,你的tensor操作得是在ko里面进行对吧,你得在变形设备上面去跑,要不然就会跑的非常慢,大家可以看一看这个例子,其实和。

其实和python ope里面操作非常非常像,但是太极scope里面知识更好一点,更好在哪呢,你如果去在太极scope里面print一个vector,或者print一个matrix的时候。

他就会直接把这个vector或者matrix给他呃,给他复印的出来,这一点是彭于冰小朋友很给力的帮忙实现,这个功能非常非常重要,以前没有这个print,整个vector或者整个matrix功能的时候。

大家都要手动的去把vector和matrix的每个item,打出来,那就非常麻烦,那现在比较方便,整个太极这个框架都会让大家努力下,变得越来越易用,在太极太极scope里面,就在太极客创里面,你是可以。

呃可以这个用print的,但是要注意一个什么事情,因为你是在并行设备上print,那你的print不一定会呃,follow在它的代码里面的顺序,这个很容易理解对吧。

你如果有20台打印机一起在往外打印东西,那谁先打印出来的东西,那你就很难说了,他们是并行的,这个顺序是没有保障的,但如果你是thread的,内部顺序是保证thread之间顺序是没有保证。

大家记得这个就可以,那么最后基本上最后了,这个太极程序有好几个face,第一个face叫做initialization,就是初始化,第二个face呢叫做啊tensor allocation。

你在这个face里面你可以去呃,所谓face就是可以认为是阶段吧,就是你可以认为有不同的阶段,首先要初始化第二个tensor allocation。

然后tensor allocation里面你可以去定义t i t vr,就是定义一个标量,tensor,tian vector,定义一个矢量和这个向量的tensor,tian matrix。

定义一个矩阵的tensor,你只能在tensor allocation,这个face里面去进行tesl的定义,一旦进入competition face以后,就不能再定定义新的tensor。

这个是一个有点局限性的地方,后面我们会考虑怎么把这个局限移除了,但大家现在还是要记住,就是这个tensor allocation和computation,中间是有一个明确的分隔的。

什么时候你就进入competition face呢,你第一次launch一个kernel,或者你在python scope里面访问一个tensor的时候。

你这你的太极就从tensor allocation face,进入了computation p,那么一旦进入computation face以后,就不能再allocate新的tensor。

当然你如果觉得呃需要砍掉重来的话,你可以点用这个t i。reset,它就会把整个东西全部砍掉,重来你就可以重新t i。in it,然后呃重新执行一个新的开机程序,当然这个一般情况下就可以。

一般情况下大家是不需要用到t i0 i,因为你程序结束的时候,你自动就重来了,那么ok讲了这么多,我们终于可以看一个端到端的程序了,这个是一个计算分型的程序,可以说是非常简单了,大概只有30行代码。

我们来看一看嗯,首先第一个每一个太极拳,就第一行都应该是什么,都应该是import touch s t i对吧,然后我们后面接下来要做的事情呢,是初始化太极。

然后我们进入了tensor allocation,我们定义一个探索,要做pixel,这个pixel呢有640x320个element,每一个element是一个float thirty。

two是一个32位浮点数类型,然后底下我们有一个function,一个kerne,这个kernel是什么呢,我们先看这个kernel,因为kernel会调用这个方式。

kneel它是叫paint kernel,painkernel传了一个时间t,时间t它是一个32位浮点数,pk里面呢我们有个并行的这个follow。

这个follow不会look over所有的pixels呃,并行的像你因为pixel之间是独立的嘛,你可以并行的渲染,每个pixel是pixel在干pixel,每个pixel干啥呢,我们去做一个迭代。

这个迭代其实就是呃在算这个julia set这个公式,你可以看到这个里面我去掉了一个函数,这个function tei。funk叫complex square,这个complex square干啥。

算了一个负数的square,这边我去abuti an vector还表示一个负数,然后大家也可以看到在太极scope里面,怎么去初始化一个vector,你可以用ta vector,然后带一个方括号。

把这个vector里面所有的元素都做成一个list,给它传进去,ok那么迭代以后我们就知道这个julia set里面呃,它的颜色是什么样,我们把它用呃写到这个pixel里面去。

那么这个kernel和方式我们就定义完了,接下来呢我们,可以比如说他已经自带一个工艺系统,这个非常有用,就是说虽然不同平台有不同的不同的工艺系统,但是为了可以置信的考虑啊。

我们自己造一个极小化的会议系统,这样大家一个人写代码,另外一个人复制粘贴就可以运行,这就非常方便了,呃这个接下来就是主循环,主循环里面去干啥呢,先调一下这个paint,调完paint以后。

我们去把配置出来,结果给它显示到故意上面,然后我们去故意点show,就是把这个故意的内容给它显示在屏幕上,这应该非常容易理解吧,我可以我应该跑一跑,好这个是我们来跑一跑,我的这个屁股。

我不要用p python 3,我的因为我经常用python 3,所以我就把它缩写作为一个字母p,所以嗯但是我怕大家computer,所以我就把全部python 3都打出来了,你可以看到呃。

这个就是frontal的这个程序,他现在正在justin time编译,因为我正在直播,所以他就可能毕业时间久一点,哇,这么卡嗯好的,我这个果然不能一边开着直播软件,一边跑程序。

但是anyway大家应该都知,如果你在正常的电脑上不开直播的话,一般是60fps的,这个大家可以课后自己去淘一淘,ok那么最后我们讲一讲一个非常重要的技能,就是怎么调试一个台阶程序。

首先你调试你可以用呃,你可以用print去调试对吧,你也可以把结果写到太极tensor里面,然后在python里面去print出来,这些都可以,但我今天讲一个呃自动的一个调试模式。

这个叫debug equals to,就是你在初始化太极的时候呢,你如果把debug设成q,他就会做一些额外的检查,比如说这点我可以呃,有一个叫shift的kernel,这个kernel干啥呢。

是knel把bi加一拷贝到ai,ok,那么呃这个其实就你看起来好像没有什么问题,但是你仔细想想,你会发现当i等于九的时候,那i加一就是十,那你就会访问b 10。

但是b这个tensor它的范围只有0~9对吧,所以说这个时候,这个其实就是数组访问越界了,那么太极在非debug mode的时候,为了性能的原则,性能的原因,你不可能每个test axis。

你都去检查一下它有没有越界,那你的程序扮成狗了对吧,所以我们只有在debug mode的情况下,才会去检查数字有没有越减,debug mode,反正你在debug,所以慢一点也没有关系,所以嗯。

你如果在debubrun这个程序,就很容易发现你程序里面有这个问题,ok这个就是数组越界检查了一个很快速的方法,那么这一部分呢我们就暂时结束了,那么接下来如果大家要学习更多的dt。

我可以去看太极的文档呃,当然以后我们每一节课都会有一些时间来介绍,这节课需要用到的泰迪的心理需求,因为嗯我觉得最好的方式呢,就是我讲一些simulation,讲一些太极,这样大家两方面都能学到。

如果我一开始花三节课讲太极,不讲simulation,那可能大家觉得学了没有用,如果光讲simulation,不讲太极了,可能讲了也没法实现出来,所以我们就,每一节课讲一点,每一节课讲一点。

如果你发现太极的bug了,你可以raise an issue,呃,如果你想加入我们一起开发太极,我们有这个贡献者指南,这些链接,这个pdf是带链接的,我可以点一个试试,应该是可以点的哇。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我一直开着这个,怪不得这么卡,好吧,我刚才不是关了吗。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嗯这是贡献者指南,然后刚才有同学问怎么看中文文档。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这边我应该讲一讲,因为中文档的同学真的翻译的非常辛苦,我觉得呃大家一定要去看一看中文文档,这个怎么看呢,就是,我看一下,其实哦你如果去太极的呃,官方仓库里面,你可以看到。

它其实是有一个简体中文文档的链接的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你如果点进去就可以看到简体中文档,基本上是我觉得真的翻译得非常的好,然后嗯我们经常更新,然后有的时候因为英文文档更新了以后,中文档才可以更新,所以有的时候中文章有一点点delay,对像这些我讲到的这些。

包括一些呃常用的故障排除问题啊,大家都呃以很和善的方式给他写的出来啊,对中文呢还是非常友好的,真的这边要再感谢一下自我中文档的同学,真的非常不容易。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我回答一波问题吧,看看,我看看有没有,tensor可以套tensor吗,哦这个暂时不行,这个但是呢有的时候嗯,我想想哦,你如果是比如说一个wandy tensor,要套一个td tenor。

那你为什么不直接allocate three d tensor呢,对吧,为什么有必要用tensor套tensor,这个是一个奇怪的需求,但是这个问题非常好,泰迪有aibm的特性,这个正在开发。

还没有没有搞,没有完全搞定,然后pdf在是在哪儿下载,这样我讲完以后,我再呃课程主页和论坛上面去更新一下,这一讲的slice,作业如何提交啊,这个后面我会讲,大家先不要走,今天大家先别走。

今天讲的稍微有点超时,但是以后我们可能都会讲一个半小时的样子,因为我现在发现可能讲一个小时,确实时间有点紧,ok这个这个问题真的很多,呃mickle什么意思,mackl就说kerne里面你可以。

随便定义各种各样的操作,这个就和,比如说如果你用tensorflow或者ptch的话,那一个看重能做什么,你可以把两个tensor加起来,把两个tensor给它乘起来对吧。

那么这个kernel就不是一个mako,因为你这个mac kero,一个kerne里面这些内容非常简单,这个有会有一个什么问题,你的计算非常容易,但是你的保存非常多,那你的程序完全就是在被保存。

立block数太极,用mega girl的话,他的这个计算就会很多,仿真比较少,他就提高了这个计算vocality,让他arimatic intensity变得更高一点,然后我看一下。

太极和python直接框架可以结合吗,可以可以,我们有拍拖时的接口,除了github,github上那几个demo,还有别的demo吗,其实是有的,后面我会讲,然后多gpu我们现在暂时还不持有。

同学问太极有没有多gpu,但是现在我们还不认识,但是之前提到的那个c bb,2020年的多gpu m p m p m paper是支持多gpu,大家可以去看那个paper。

但是怎么自动的用一个编译器搞多gpu,这个还没有,我还没有想好怎么去实现,这是一个很好的研究的问题,菜鸡加速比较快的应用有哪些,光线追踪渲染可否。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

虽然有同学这么对光线追踪感兴趣,我就跑一个光线追踪看一下吧,但是这个问题是跑了以后我可能直播就掉线了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我试一下吧,叫sdf render,因为他这个非常的费资源,我就有点怕电脑非常卡,因为这个电脑非常非常老,那编译的时候我再看一看别的,问题有个同学说要送我电脑的,这就不必了,我我这个电脑用的挺好的。

这还能不能跑出来,这个实在太卡了,现在它既可以用来做布料仿真吗,呃可以可以,你可以写一个简单的布料仿真,但是真的布料仿真的话,那他很多地方其实最头疼的事情,是布料的自香蕉嘛,不相布料自相交。

现在时髦的搞法是用rtx什么retracing hardware,去做这些东西,我布料我其实不是专家,所以我只是说能写一个比较挫的哦,诶居然能跑,可以啊,这是这个一个简单的光线追踪render。

我来把它取关了啊,这个代码非常短,这个代码只有100多行,大家可以去看看,那这个材料就非常的简单啊,然后这个geometry是用s d f去绘制的,然后大家如果真的要学rendering。

那肯定要去看杨老师的课,我不是rendering方面的专家,但是我是我知道一些,怎么把代码写的比较短的trick,然后这个是一个我不能再让他跑再跑,这个风扇要起来,大家都嫌吵,赶紧把它掐了。

ok那我们看一下这个代码其实非常短,就100多行,大家有兴趣的话可以去看一看对好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么最后一部分应该还有几分钟,我们讲讲作业。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个课的作业啊,其实工作量可大可小,因为毕竟有同学反映这个,有同学反映这个呃可能特别复杂的作业,可能会做不动,然后也有,当然也有同学非常积极,肯定觉得很想就上个这个课,然后自己写一个物理题出来。

这个肯定也是可以的,所以我们就作业就分成了两部分,五次简单的编码练习,coding exercise就非常简单,然后没有我们会提供标准答案,但是建议大家看答案之前自己先尝试尝试,这个我们不改。

大家也不用提交,大家就呃自己尝试尝试,然后第一次呃课,我大概可能明天后天,我release一个一些简单的编码练习吧,然后大家在这期间可以跑一跑太极的各种excel,然后看一看已有的太极代码长什么样。

然后我们有三个开放项目,开放项目可以呃1~3个人组队,希望大家都能玩得开心,然后嗯开发项目呢我们会有评奖,然后,获奖作品会在课上点评,然后呃获奖同学呢会收到我们的一个神秘礼物,这个礼物具体是什么。

大家到时候就知道了,那这些作业都是自愿完成的,这个我们没有任何强制的,大家可以根据自己的口味适当添加,嗯说的好像跟方便面里面的这个调味料一样,但是大家我们这个课会照顾到各种水平的同学。

然后但是我还是要强调一点,就是说呃纸上得来终觉浅,觉知此事要工行啊,这个实践真的非常重要,我觉得我从我的计算机统计学,基本上就是靠自己去实现各种各样的代码,学习了你在看懂文。

写代码的过程中就能学到很多东西,不一定要一个老师去指导,你就自己看这些东西,对自学能力有很大的提高,然后对代码能力有很大的提高,你如果要做计算机图形学的研究或者工程的话,代码问题非常非常重要。

所以虽然作业不是强制,但是我觉得想呃有收获的同学,最好还是积极参与一下这个作业的这个项目,那么第零个作业,第零个作业,这个不算在三个开放作业之中,这是一个非常轻量级的作业,然后这个作业是什么呢。

首先你装好太极对吧,如果你是python 3。6加的话,你可以直接嗯tap install太极,然后嗯这个好像写错了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

是不应该p更有意思,不好意思。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你转好太极以后,你可以尝试运行一些呃太极的example,你可以呃python 3杠m太极example。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如说m88 ,我可以run一些现场run一些,呃就是说run太极的excel有两种方法,如果你是装的太极的呢,你可以打ti呃,example,他会告诉你有哪些可以运行的example。

比如说他会告诉你啊,这些这个是网友贡献的学者,真的非常非常有用,如果说你没有提这个指令,有些有些同学可能反映装了太极以后,没有提这个指令,你怎么办呢,用python 3杠m太极,这个和ti是一样的。

你可以判三杠零太极,然后sample我们来跑一个,比如说m p m128 ,这个这个128好诶啊,不能加点开。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个是个128行的npm代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它是一个可交互的,我不知道这个这种情况还能不能跑,还能跑,你可以用鼠标去拖一拖,给他增加一些引力啊什么的,但是这个电脑实在太卡了,所以跑到60f p s这个也没办法,我还开着直播嗯。

这是一个比较呃交互的代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我们再跑一个别的跑一个,比如说跑一个sql fli,诶,好就不要加点拍了,如果是t2。3步就不要点开了,那这个是也是一个交互的例子,我们可以在里面画一画,画一画水波,但这个可能比较廉。

这个我们后面会讲到高级输送格式的时候,这个我们就我们就会提到,怎么样把数值连性降低。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在这个数据点有点高,我们可以再跑一个别的,刚才sdrender跑过来跑一个,换一个水波吧,我只会要不老是把胎带上,这个是彭于冰小朋友写的,很有意思,你就呃化学水平它会产生折射这个代码。

这些代码都非常简单,大家可以去看一看,非常适合入门,比如说我我可以给大家看一下,比如说npm 1888,这代码非常短,就真的只有128哈,我不是说什么,通过各种压缩把它当128行,那就真的只有这么长。

然后还带一个gui,就是interactive,这个在没有太极的时候,你要写这么个程序,你可能这些以前很难吧,我觉得而且换一台电脑还跑不了,我们再看一下water wave,这个也很短,就100行。

它其实就是一个应该叫final difference,time to make一个sober,我们再跑一个别的,有没有什么别的能跑的,比如说跑一个这个可能要box,我不敢跑,可能要box跑了。

我这个可能电脑就挂了,你套一个game of life,这个是一个比较简单的生命游戏的这个demo,神秘游戏的这个提出者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

前一段时间因为新冠肺炎去世了,真的很可惜,这边我们就呃跑一下它的得意作品。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

行我们我们我们刚才展示几个example,然后当然这个作业最重要的一部分了,就是大家动手写一写自己的采集程序,嗯我一直相信啊,这个熟能生巧,然后很多事情倒并不是说像媒体吹的那样,什么呃。

一个人呃天生智力有多高,或者什么不费吹灰之力就做到什么,但你会发现大部分人其实我我不认识这样的人,我认识的人都是好好努力,然后好好练习,然后最后才达到一个比较熟练的程度。

然后最后当然会呃媒体会各种造神啊什么的,但是你仔细去看他们,他们其实都非常努力,然后我觉得大家如果要想掌握这个编程语言,要练习要多练练习还是非常必要的,那么当然啊,如果你写了程序呢。

请一定要把它和你的同学们share在这个太极的呃,论坛上面,这样你太极非常portable嘛,你这个你自己写的程序,别人很容易运行啊,这边有几个问题,我得课后再来回复了,但你可以写一个帖子。

说我自己写又写了一个什么程序,我给大家分享一下,大家呃看一看指出一些什么问题,然后自己跑,然后别人跑一跑也很开心嘛,这个别人给你提供点反馈,也能学到很多东西,然后因为毕竟这个课上的人很多很多。

我们呃我还以及我们的助教团队,真的经历非常有限,因为太极本身还有很多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随着课程的进展,我们太极本身还有很多feature需要去开发,所以我们压力真的非常大,所以大家相互学习,这样我们这边就省事一点,我们就能更专注的把这个课搞好,那么如果说你想让你的程序被我们选中。

在课上展示的,那请早点把它结束,因为我们会在课程开始之前,二四十八个小时去选比较好的作品啊,因为我们需要时间去做决定,我们不可能说五分钟选一些中期出来对吧,嗯在follow里面。

大家最好能提供一个截图以及提供源代码,你可以在github上面他一个repository,然后去存你代码,你可以在论坛上面放一个链接啊,这这次是有奖品啊,如果大家被以后也是都有奖品。

如果以后大家呃程序被选中,被我们点评的话,都是有奖品的,那么最后我们介绍一下助教团队,然后我们助教嗯,有主要团队呢有分理论组和技术组,理论组同学主要负责在论坛答疑,然后筛选一些优秀的项目。

然后技术组主要负责与客人相关的,太极的各种开发与维护,因为毕竟太极现在是嗯还是处于一个比较早期,现在可能是全世界,也就嗯稳定的用户可能就30个吧,然后可能也就几百个人用过。

然后这次大家一下子来都变成稳定用户了,那肯定会发现各种各样的问题,当然我们之前已经竭尽全力修了很多的问题了,现在呃应该说不会有特别明显的问题,至少cpu by cat上面是兼容性是非常好的,呃这边对。

然后我们呃真的非常感谢,我,非常感谢八位主教,能够愿意帮忙,去参与到这个非常有意义的项目中来,因为呃我觉得我小时候就没有这样的课程,我都得自己去看各种英文的slide,那个时候看的非常费劲。

然后现在10年过去了,我希望我们这个课如果说能够启发一些同学,然后10年以后这位同学也能像我一样去呃,给大家开一个课,然后讲讲更高级的东西,那我觉得这个是对社会。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GAMES201:高级物理引擎实战指南2020 - P10:Lecture 10 总结 - GAMES-Webinar - BV1ZK411H7Hc

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

欢迎大家来到我们课程的最后一讲,不知不觉啊,感觉时间过得真的是非常快的,从我们第一讲到今天,其实才过去了两个多月,应该差不多三个月,基本上在北美这边三个月,时间差大概就是一个暑假。

所以大家相当于用一个暑假的时间,基本上学完了这门课程,真的还是非常不容易的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok所以在讲之前,我们首先还是要炫耀一下,这个作业二的各种获奖作品,然后虽然这次作业二真的时间非常紧,然后有很多同学反映正好遇上期末考试,有很多同学反映正好工作上事情很多。

但是还是有12位同学提交的作品,然后当然我们会给这12位同学,都寄一份精美的纪念品啊,就是所谓的太极茶杯呃,这次时间比较紧,还没有来得及去写一个知乎的知乎的文章,不过后面会找到时间的话,我会去写一写。

让更多的同学,特别是课程以外的同学,能够了解到大家在这门课上做出来的,这些精彩的程序啊,欢迎大家课程结束以后继续提交,但是如果你后面提交的话,那可能就得等比较久才能收到截屏,因为我们课程结束以后。

课程的整个组织其实会更加的松散一些。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们还是要安利一下这个china vr,上面的太极竞赛啊,然后之前有很多同学反映报名表太长了,然后报名表成为了一个报名了很大的阻力,所以我们后来又做了一个,一分钟完成报名的报名表。

这个报名表就非常简单了,如果大家可以呃点开这个链接,或者去打开二维二维码,其实只有四个问题,其中只有三个问题是必填的,希望大家都能去呃尝试报名一下,然后我们奖项设置还是非常的丰厚的,有特等奖一个。

一等奖三个,二等奖六个,然后三等奖和优秀奖若干,基本上你只要完成一个合格的提交,都会拿到某种奖项,如果你做的非常好的话呢,当然还能拿到特等奖或者一等奖,这样的很不错的奖项,竞赛的网站我也放在这了呃。

还是请感兴趣的同学能够多多参加好,那在正式开始讲今天的内容之前,首先要恭喜一下各位,因为大家掌握了各种各样的新技能,这些技能包括一门新的编程语言,基于物理的模拟的各种呃各种算法,然后各种数值线性代数数。

各种数值线性代数的方法,然后还有一些像现代计算机的处理器微架构啊,类型层级啊,并行编程,g pu编程,各种高性能计算,一些入门的知识,还有吸收入结构和口味编程,这两个太极的独特的功能。

那么我觉得能把这些知识都掌握,甚至都入个门,其实还是要花不少精力的,然后这门课难度真的是不小的,能坚持到最后的都是勇者,大家应该给自己鼓个掌,然后我也给大家送上一个太极人专用点赞来啊,感谢一下大家。

也恭喜一下,大家好,那么我们今天讲什么呢,今天主要是我的一些私货了,就是说我在建设,我在呃构建屋顶擎和太极这个项目的时候,所学到的知识,如果说让我必须只能用一个词来概括。

我这10年来从这个事情里面学到的事情的话,这一个词就是simplicity,简单简单很好,然后我后面会呃来论述为什么简单是好的,然后讲完这个以后,我会讲讲物理琴,简单讲讲物理引擎的未来。

然后简单讲讲自己我自己在课程中的收获,然后最后感谢一下呃,各方面为这门课程提供支持的老师和同学,刚才提到,如果说只让我用一个词概括,我在物理琴和太极这个项目里面,各种各样的项目里面学到的东西的话。

这个词一定是simplicity,就是简单性,那么说到这个simplicity,很多同学可能还在学校里面读本科,或者在我不知道有没有在读中学的同学,我猜大部分同学应该是在读本科。

但是如果有读还在读中学的同学,可以在呃公屏上面打一个一,证明一下自己的存在,ok,当然你如果在基础教育或者在本科阶段的教育,说白了学生最重要的一个事情是,你你得把考试考过对吧,然后考试的时候。

你要去做的事情是证明自己会某种方法,你需要证明自己会,但是呢当你去本科毕业以后,你去工作,或者你去读ph d所研究或者做一个工程的时候,这个时候你往往需要的最重要的能力,是证明自己能找到好的方法。

当你离开学校以后,当你离开考试的环境以后,有很多的情况会改变,第一个事情会改变的事情,就是说你有自己选择方法的权利,第二个很重要的改变因素是你需要与他人合作,然后这两个因素使得找到一个好方法。

非常的重要,往往在你脱离了学校,学校这个环境以后,一个很重要的事情是用哪种方法并不重要,重要的是系统性的解决问题,解决问题是最重要的,方法不重要,一天只有24个小时,这个看起来三岁小孩都懂。

但是其实你要意识到自己时间是有限的,这个其实并没有那么容易,然后聪明的人都是一样聪明的,这句话不是我说这句话,是有一次我和杨奇志老先生吃饭的时候,然后他给呃一班的同学说的,就是说呃聪明的同学都是一样的。

聪明的,你不可能指望说有一个其他的人比你聪明十倍,它不可能长十个脑子对吧,你这个大脑毕竟还是一个生物的构造,它不像这个微电子里面的这个摩尔定律一样,它可以18个月transisters翻一倍。

它不会怎么增长的,你这个大脑容量就是有限的,在时间和脑力都非常有限的情况下,我们必须采取的一个措施是,用简单可行的方法去解决大部分简单的问题,因为世界上有很多难题是真的非常复杂的,你必须用简单的方法。

用最少的时间把简单的问题解决了,才会有时间去解决真正复杂的问题,别把时间都浪费在解决简单的问题上面,那你就没有时间去解决真正复杂的问题了,有影响力的创新往往会伴随着复杂性的减少,这个其实也很有意思。

很多同学觉得新的东西一定会更加的复杂,但往往并不是这样,那他你会觉得它更加复杂,但是你在接触到他之前,发明他的人,往往已经对他进行了最大程度的简化,这个其实呃有点像日本文化里面的,一个是一个宗旨。

就是说不要给他人带来麻烦,我在日本待过小半年,然后我在那边,这个他们的文化里面有一个非常有意思事情,就是千万不要给他人带来麻烦,但是这个不给他人带来麻烦,有很多极端的做法,这边只是呃overall。

大家体会一下,就是说你要发明一个新的东西,必须要让你的用户能够轻易地使用它,你造出来的东西必须能够啊,必须是简单的,必须不能给他人带来麻烦,如果说你写了一个paper,你发明了一个新的算法。

没有人能够正确使用它,太难以使用,那么就那你这个paper指它的呃,能产生impact是非常非常有限的,如果你说你写了一份代码,非常难以使用,非常难以读懂,那么如果你在和他人合作的时候。

你这份代码可能根本就不会出现在,最后的代码库里面,因为reviewer会把你代码cu掉,因为他不懂你这个到底在干啥,即使你有幸的这份代码能够进入,进入到最终代码库,最后它的维护测试。

包括它的正确性都非常非常难以保证,ok那么刚才说到简单性是好的,反过来说就是复杂性是坏的,那为什么复杂性很坏呢,因为首先像我刚才说的那样啊,如果你有一个非常复杂的东西,那么其他人不能理解你在做什么。

你要知道其他人不见得和你有一样的背景知识,哪种东西其他人不一定懂,所以说你如果刚提出来一个非常复杂的东西,那没有人能懂这个做的东西,它的产生影响力就非常非常的小,然后啊一个复杂的东西你要把它int起来。

你要实现它非常的缓慢,然后往往你非常难以feel quickly是什么,叫feel quickly,就是快速失败,为什么要快速失败呢,因为你如果做科研的话,你就会知道99%的i d。

99%的想法都是不work的,那剩下的1%里面,可能有90%是被前人尝试过的,你只有可能剩下的只有1‰的,这些想法是能work,那你必须要去在你精力是有限的情况下,并且大家都一样聪明的情况下。

你如果还想能做出有意义的工作的话,一个非常重要的事情,就是能快速的知道这个方法,workb,你必须要能够fail quickly,如果你有一个非常复杂的想法,它实现起来非常费时间。

你很难非要quickly,因为你不知道到底是自己实现对,实现错了还是这个方法本身,不过你很难区分到底是方法复杂,还是自己没有实现好,这个其实是复杂方法的原罪,这个就引出了第三点,复杂的方法更容易出错。

而且出了错以后,你很难去分析它,因为它其中的成分太多了,你不知道到底是哪一部分搞错了,很多复杂的simulation的算法,你可以去看看很多复杂的非常非常复杂,simulation算法。

它这些论文虽然最后能发表在secret上面,但是随着时间推移,很快大家就忘了这个算法,因为太复杂,没有人能够正确实现的,就算你是你,就算你实现代码能力足够强,你要知道。

看着一个paper实现这个算法其实是非常难的,如果你不给代码的话,因为你如果实现了半天,发现他不会,那到底是这个paper有问题,还是说实现的不对,还是说自己对paper的理解有问题。

还是说各种各样其他的原因,你很难知道到底是什么原因,导致这个东西不那么啊,后面我们会提到这个,其实你甚至可以说这个是不科学的,因为你不能证伪它好,然后复杂性还有一个很坏的事情。

就是说你有一个很复杂的算法,不管是你手写也好,不管是编译器帮你编译也好,它都非常难以高性能的实现,这个就其实很有意思,大家会觉得复杂的算法往跑的更快对吧,但是其实实际情况下并不是这样的。

因为你复杂的算法首先你得实现,对对吧,你假设你能把它实现对,还记得上一讲吗,上一讲我们提到对一个算法,你如果考虑上计算机体系结构,考虑上各种高性能计算的各种技巧,你是能够把它提高十倍乃至20倍的速度。

但前提条件是什么,前提条件是这个算法足够简单,如果说你给我一个一段普通的你随手写的程序,我可以花一些时间,我重写一遍,可能能快个十倍,20倍,这些一般都是可行的,但是如果说你给我一个非常复杂的程序。

我即使知道我花很多时间,我能让他快十倍20倍,我可能都没有动力去做这个事情,为什么,因为太复杂了,太烦了哈,大家懒得帮你去做性能优化,所以啊你要实现一个高级的算法,它首先得是简单的,它不能太复杂。

复杂了以后没有人能知道怎么去把他高兴的话,因为高性能本身就是一个复杂性,然后人能handle的复杂性是有限的,如果你这个算法本身非常复杂,那剩下来的能够接受的复杂性就非常小。

那么代价就是你在剩下来的这个你的脑力里面,你其实能够用在优化它的,这个部分是非常非常少,所以最后导致结果就是复杂的系数,数据结构也好,自适应数据结构也好,复杂的网格也好,然后复杂的数值格式也好。

最后都会败在暴力解法之下,什么是暴力解法,就是稠密数据结构啊,一阶精度的这个有限元或者呃npm,然后呃当然这不绝对了,有限元大家还是有的时候会用很高阶精读的,然后但是另外一种方法就是离。

就用一阶精度的元素,你把它分辨率吹得很高很高很高,虽然在鉴定意义上这个可能不太行,但实际情况下往往就不错了,你特别是在你写physical ver的时候,你如果把你sover搞得非常复杂。

那编译器也会很难优化你的代码,你要知道编译器,它也是会遵循一些规则去分析你的程序的,如果你程序非常复杂,非常难以去分析的话,那编译器也会很confuse,他不知道你这个代码在干啥。

然后生成的代码质量也会受影响,ok那么既然复杂性这么坏,为什么大家还会把东西搞得非常复杂呢,大家可以想一下这个问题,答案或许出乎我们的意料,答案是什么呢,because it’s way。

easier to be complicated than to be simple,搞出复杂的方法比搞出简单的方法简单多了,听起来可能有一点矛盾啊,就是复杂的方法比简单的方法容易搞出来。

这个可能在英文语境底下更容易说,在中文里面反而听起来有一点有一点令人迷惑,但是总体的意思就是说,对于大部分人来说呃,如果你家精力有限,然后经验有限,各种情况,各种资源都有限的情况下。

你搞出来的方法往往是比较复杂的,而不是简单的方法,ok我们来看一看,我们来看几个具体例子,为什么有很多情况下,大家会喜欢把东西搞得非常复杂,那么第一个动机就是说证明自己很聪明,这个其实是我们的教育里面。

它存在的一个很有意思的现象,就是说我需要通过一些呃复杂的方法,来证明自己和其他人不一样,证明自己嗯很聪明,因为大家的直觉就是说哇你懂这么难的东西,你一定很聪明吧对吧,这个在学校里面或许是一个好的注意。

你可能通过做一些难题,或者通过做一些大家都不懂方法,显得自己独一无二,鹤立鸡群,然后嗯很聪明,你在学校里面或许这是一个好主意,但是实际上当你需要去和其他人交互的时候,这个几乎永远不是一个好主意。

为什么呢,因为你如果去看一看,你做的项目的比这个更大的图景,你从更大图景上面来看,你的这个项目或多或少的他的其中的关键因素,就是你能不能和其他人有效的沟通,你的想法能不能从你的脑子里面。

精确传输到另外一个人的脑子里面,如果是一个简单的方法,这个这么简单方法的沟通已经很challenging了,已经很难了,沟通是最难的事情,沟通比写代码难多了,然后简单方法的沟通已经很难了。

更何况一个很复杂的方法,所以一旦你要和他人沟通的时候,going complicated绝对不是一个好的主意,一定要把事情简化简化简化再简化,我记得有一个研究说,人的语速一秒钟只能传大概十个bt。

也不知道十个bit,反正这个速传输速率是非常非常低的啊,所以呃这就是为什么简单精炼的一些方法,能够流传得很广,ok那第二个重击呢就是show off the amount of work。

证明自己做了很多东西,我记得这个很有意思,就是说有一些课程项目他会期末考试要求你,比如说写一个五页的报告,或者写个十页的报告,结果你搞了一个方法,你发现诶这个报告好像只能写一页,那怎么办呢。

我是不是可以把我的方法搞复杂一点,这样我就能凑到五页或者十页了,你看这个学校里的学生往往会有这样的思维,就说我老师要求的这个必须得写实验,这个方法必须要有复杂性,呵呵实际情况下呢。

你从学校里面大家可能更加的过程主义,大家看你这个解决问题的过程,因为它的目的是让你学会解决问题的方法,而不是让你把问题解决,但是当你脱离了老师,脱离了学校里面的环境,脱离了这个考试的设定以后。

你去真正解决实际问题的时候,who cares,谁在乎你用什么方法去解决问题呢,你只要把问题解决好了就行了,你只要把在合乎合乎道德,合乎逻辑的情况下把问题解决好了就行了。

所以大部分专家并不需要去show off,你的amount of work,并不需要去展示你做的你都做了什么,o那么第三个把事情搞得非常复杂的动机,就是隐藏隐藏错误,然后这个或许也有点反直觉。

但这个逻辑其实也很容易理解,因为有些人会这么想,有些人觉得呃我做的这个工作里面可能有错误,那怎么办呢,我把它搞得非常复杂,这样就没有人证明我是错的,因为没有人知道,没有人理解我这个东西到底在干啥。

所以我就是对的哈,这个逻辑大家能理解吗,这个其实也是一个很很有意思的一个逻辑,说起来很讽刺,但是有些时候势必会有人这么做的,这个其实当你这么想的时候,那你其实已经开始违背科学的精神了。

因为有一个表述就是,卡尔波普尔对于科学的定义在于,就是科学和其他的,应该怎么说科学的独一无二之处,或者说科学必须满足一个特性,就是它是可证伪的科学,你如果在科学的体系里面去论证一个东西。

那你怎么说明它是科学的,就是说如果我这个argument,我这个论断是错的,你是可以去证明他的,你是可以去证明他是错的,如果说你把一个会搞得非常复杂,它既不能被证真,也不能被证伪。

那这个东西它就是not even wrong,连错了都不是,它不属于科学讨论的范畴对吧,ok那么第四个把东西搞得非常复杂的,原因是希望和prior work区分开来。

然后呃这样你的paper就可以被接收,要不然reviewer你写了一篇paper,然后方法非常简单,之前可能已经有人做过了,然后呃你的reviewer就会说啊,你这个方法和之前某某某paper做的一样。

你这个paper我要去了,所以呢这种情况下,有些同学啊,特别是一些呃做研究的同学,他可能会把方法搞得非常复杂,比如说这边打个补丁,那边打个补丁,使得它看起来和之前的方法不一样。

然后review在考察这个方法,到底之前有没有做过的时候,就看诶这个方法好像非常复杂,那可能之前确实没有人做过吧,那么至少在创新,创新性上面就不会再来质疑你了,那这么做可不可以呢,这么做当然是可以。

如果你的目的就是让你的论文被接收的话,这么做是完全可以的,那如果说你的目的就是我读一个ph,我的目的就是尽快的毕业,然后呃我要发表足够数量论文,这么做是完全可以的,也有很多人确实就是这么做的。

但是如果说你真的希望,你的文章有很大的影响力,那最好还是别这么做,因为这些东这些文章做出来,说白了大家就叫做incremental work,资金量性的工作,或者更难听一点的说法。

就是如果你把这个推到极致的话,那大家就叫他灌水了,就是说呃我把一个方法这边修修改一下,里面修改一下,把它搞得非常复杂,本身的这个原来想法的这个精简性就没了,然后就搞出来一个非常复杂的算法。

这种paper投了也能中,但是呃一般来说很难产生很大的影响力,那么第五个motivation,为什么大家会是把这个想法搞得非常复杂的,就是懒得去简化它啊,懒得去简化它,这个其实是很有意思的一个事情,呃。

因为一个想法诞生的过程,往往可能是20%的时间是在想这个东西,然后后面80%时间是在去简化,你这个东西,你可能20%时间做个雏形,我就做一个写上一坨乱七八糟的代码,然后花80%的时间去简化它。

使得得到一个最小份的代码,它还能够工作对吧,那如果你只花钱买20%时间,你就只用了别人1/5的时间啊,你也能得到一个非常复杂的算法,ok然后这种情况下,如果把百分之后面80%忽略掉的话。

那就相当于懒得去优化,那这样其实也是可以的,但是你如果希望别人能够理解,希望你这个呃从长远角度来看,你这个工作很有影响力,那最好还是花一点时间去简化你的想法,然后最后一个很有意思的事情是就是呃。

之所以很多人会把事情搞得非常复杂,是因为audience being too nice to tolerate,这就是一个很有意思的例子,就是我记得当时我在姚班上一门课,我记不得是什么课。

但是这个课的老师就是说,如果你的方法非常复杂,我们看了半天也不知道它是对的还是错的,我们会当做错了来处理,这个,其实在大部分情况下呃,甚至有些人在考试的时候会故意写出来,写出来一坨显得自己好像懂得很多。

然后呃阅卷老师可能会觉得诶,这个同学写了这么多,我我虽然不知道他是对的还是错的,好歹给他个辛苦分吧,给他个比如说十分,给他个两三分,这样其实就是其实纵容了这种,把事情搞得非常复杂的这些想法。

但是这个这种事情只会在学校里面出现,在实际的过程中,没有人会appreciate你这种做了很多工作,最后没有人能够理解的这种事情啊,对我记得当时那个老师就是说,如果说你不会,那你就写你不会。

我会给你三分,但是你不要说你不会,你写上一大坨,这样我作为阅卷人,我也浪费很多时间,你也浪费了很多时间,ok对,所以你看其实大家有各种各样的动机,会去把事情搞得复杂,然后呀还有一个有意思的事情是。

大家会觉得用简单方法的人很傻,是这样吗,其实并不是,绝对不是这样,实际上世界上最聪明的人都知道,把事情搞简单的重要性,我们来看看,爱因斯坦说任何事情都应该被搞得呃,as simple。

as possible,but not simpler,就是说,我应该把我们应该把任何事情都搞得,尽可能的简单,这其实是物理学里面的一个原则,就是说你得相信,这个世界被一些简单的定义来描述。

要不然你都很难去研究这个世界,这个是c加加之父,他在cpp com,cpp com是一个c加加会议,他在这个会议上面给过很多的talk,很多都是关于简单性,因为c加加,现在已经变成了一个非常复杂的语言。

然后他现在呃,当然可能很早,大家就意识到这个语言变得太复杂了,然后我们应该把它变得简单一点,然后再加下支付物流,发过很多这样的演讲,这个是他的演讲中的一个叫做make simple task。

simple,把简单这个怎么说,用简单的方法解决简单的tasks,用简单的方法解决简单的任务,being too clever is not clever,表现的太聪明,并不是聪明人的做法,为什么呢。

他举了一个很有意思的例子,我今我很喜欢这个例子,他就说调试一个程序比写程序还要难两倍,因为大家写程序的时候,大部分时间并不是在敲键盘上面,大部分时间是在调各种bug上面,在第八个程序对吧。

那如果说你在写你的程序的时候,已经把你的全部脑力都用上了,那你调试的时候就没法调试了,为什么,因为你竭尽全力才把代码写出来,那挑事又比写代码要难,那你就没有能力去调试它了,大家能理解其中的逻辑吧。

这其实是一个很精辟的话,就说每当我看到呃,各种太极社区里面的pr搞得非常复杂也好,或者说呃我和我的学术上面collv的,我看到他写非常复杂代码的时候,我就会呃援引这些例子,首先调试比写代码难。

如果你写代码的时候已经搞得很难,那你怎么调试的,第二别人来接替你的,别人来在你的代码上继续工作,比你自己在你自己的代码上工作呢,如果你自己就把写代码的时候,就把代码搞得非常复杂,那你找谁来解体。

你只能找一个比自己更聪明的人来解体,但是问题又来了,在m i t或者在姚班这样的地方,大家都一样聪明,那你上哪儿去找这样的人,很难找到这样的人的,那么最后结果就是你的项目就自己死了,ok。

我们来看看这位图灵奖得主他的说法,这个这位图灵奖得主,他是霍尔,他是80年的,从你讲得主,然后他发明了一个算法叫做快速排序,然后呃他来他怎么说呢,呃他说有两种软件设计的方法,第一种是使得软件足够简单。

以至于显然没有错误,第二种呢是使得软件足够复杂,以至于没有显然的错误,第一种方法难得多,你可以看到它的第二种方法其实是他所谓的,第二种方法,就是说就是我们之前提到的,把一个事情搞得非常复杂。

这样就没有人能指出他其中到底哪里错了,一个常见的做法是你发明了一个算法,你发现诶这个算法在这种情况下会错,我给他打个补丁去特殊判断一下,在那种情况下好像也会错,我给他打个补丁,特殊判断一下。

最后你得到了一件满是补丁的衣服,那现在我问你这个衣服它有没有动,你很难说对吧,因为补丁太多了,他我怎么知道他到底有没有动,那我不知道他有没有动,或者说我很难指出他哪里有动,能证明它没有动吗,并不能对吧。

然后这个是17年的图灵奖得主,他给在google给我一个talk,然后他应该在很多地方都给过这个talk,叫做how to have a bad career,如何毁掉你的职业生涯。

这边他列出了十个毁掉自己职业生涯的十个tips,十个做法,但这他在说反话了,这个他的第二点是,let complexity in your guide,让复杂性指指导你,他其中说到两点。

其实我们之前也提到,it’s easier to be complicated,把事情搞复杂是很简单的,这个其实很多人意识不到这一点,他会觉得复杂的东西就是复杂,简单的东西就是简单。

然后其实你在真正你做research也好,做engineering也好,打补丁把事情搞复杂永远是简单的方法,而提出简单的想法能解决问题,这个往往是最难的,然后他也提到,如果说呃我的这个方法很简单。

那我怎么能显示出我和我的同同事们的,优越性呢,啊我怎么能显示出我比我的同事们更聪明呢,如果我的方法很简单的话啊,这其实是一个讽刺的反话了,其实并不是这样,往往说一个呃最伟大的想法都是很简单的。

好像说了这么多,其实都是一些抽象例子,我们来看一看我自己的体会,比如说我以前做过一个paper,它叫做chin queen,然后这个paper发在eca 2019上面,然后这个paper一开始的目的。

就是要去做一个可微分的npm sober,但是呢在做这个项目的时候,我们还没有一个争论性的auto jeff系统,我们必须手动的去求它导数,我当时求这个导数求的真的非常痛苦。

然后由于求导数你要用很多chain room嘛,所以我就把这个chain这个词,塞到了项目的名字里面,然后这个项目就勤快,但是当时有一个非常好的事情,当时我们已经有m m p m。

这个是一个比traditional mp m,比传统的b spm p m要简单很多的算法,正是因为m sm片非常非常简单,我们才能够在25天之内做出一个ecrapaper。

然后并且能正确的把它这个导数推出来,如果你给我一个非常复杂的m p m算法,我根本就不会去推拿导数,因为太难了,推不对,这个人的这个脑力是有限的,如果搞搞得非常复杂的,没有人能正确求出发的导数。

ok所以说如果说没有这个简化版的mp,后面我们有很多工作都是做不了的,那么后面呢大家会知道我们有自动微分系统,我们有一个叫做def type的这么一个项目,它的目的其实就是进一步简化这个呃。

可微编程的过程,再也不需要去手动求导数了,再也不需要求生动求导数了,那当时我推这个导数是非常痛苦的,这边呃其实就是这么一坨公社啊,反正你要把他们推队还是要花点精力了,然后啊一言难尽,一言难尽。

另外一个例子,那么太极它其实它的之所以存在,它存在的目的就是把一切东西都能够简化,一些东西做了简化,那么有一个算法叫做multigrade,pc g m g p c g这个多重网格预条件。

共轭梯度算法用来解linear system,大家还记得吗,解了一个personance equation,这个算法,它的流程其实还是挺复杂的,然后一般大家都不愿意去实现的,因为太难了。

但是呢在有个太记以后,我可以只用80分钟,用300行代码把这个算法给他实现,这个80分钟是我从我的git log里面去,我看两个commit的实现前和实现后,差了是80分钟,然后啊。

这是因为太极这个编程语言非常非常容易,我才能做到这一点,如果你给我一个非常难用的工具,你给我个c加加或者给我扣的,那我绝对不可能在80分钟之内,写一个gpu的mgp cg出来。

game 201做了什么呢,game 201把太极的这个idea继续推了一步,现在所有的人都知道怎么去写一个multique server,我看大家交的作业里面很多都是用上了multique。

可以说现在multi的这个mg p c,这这这个算法在中国的物理模拟的圈子里面,这个代码可能已经人手一份了对吧,大家都会写这个算法,所以你可以你会你可以看到呃,从这个很少有人能正确实现。

到我自己能轻易正确实现,到大家都能轻易正确实现,这个其实是有一个过程的,这个其实大家是付出了很多很多努力,当然大家好才是真的好,我们最后一个算法它的最终归宿,好的归宿就是被大家都能掌握。

坏的归宿就是被大家都淡忘,当然呃mg p cg本身不算是一个非常简单的算法,但是呢嗯不过我们现在有台词了,你可以用很简单的方法把它实现,好那么说了这么多呀,其实就是如果让我用一个词概括。

我从写物理引擎和build,太极这个项目里面学到东西,那这个词interesting licity,ok简单性,简单性是非常好的好,那么我们下面来讨论第二个话题,第二个话题是物理琴以后会长什么样。

或者说现在物理琴还有什么能够提高的地方,那么我们回顾一下,一开始我们的很有雄性的目标是什么,是在计算机里面模拟the world,模拟这个世界,那我们做到了吗。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到呀,即使是现在最好的物理引擎,即使是各种游戏物理引擎也好,然后面向v f x这种,说什么离线的物理引擎也好,他其实并没有实现这一点,为什么呢,有好多地方其实都做的很很不好的,比如说易用性。

你怎么快速正确设置参数啊,你这个狐狸狸里面这么多拉杆,这么多参数要设置啊,你把一个艺术家让他来操作这个东西,对他说就跟开飞机一样,它会是一点啊,一脸蒙圈呢,他不知道这个东西到底各个参数怎么设置。

然后呢这个就是牵扯到下一个问题,健壮性啊,你可能手稍微抖一下,你这个simulator就炸了,比如说呃数值不稳定啊,cfl condition被违反了呀,或者各种各样的这个矩阵本来是对称正定的。

现在变成对称不镇定了,各种各样的问题就会出现,所以怎么写一个健壮的physical simulator,其实也并没有被很好的解决,所以你看到这个,当你去了解了物理性以后。

你会发现它其中能做的事情还是非常非常多的,完备性,多种材料耦合,现在我们真的做到,任意的多种材料能够耦合了吗,其实并没有对吧,m p m里面勉强能够做到各种地方,这个solid那个耦合怎么和钢铁耦合。

怎么和烟雾耦合,怎么和这个呃各种各样其他东西耦合,其实现在大家也没有很好的解决方案,特别是当你一定要做到完备性的时候,你往往会牺牲许多其他的性质,比如说易用性,健壮性或者真实感。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现代物理已经足够真实了吗,或许吧嗯这个是一个,这个是今年蒋老师的一个m p m paper,这个是模拟一块东坡肉,然后这篇paper呢其实是在呃这个真实感上面,又往前推了一步。

就说以前npm他的fracture,它的这个破碎是iso tropic,然后是这个各项同性,但是东皇这个东坡肉大家都知道了,这个肥肉它上面有一层这个皮肤,这个皮肤它是一个你把它剥离开来。

它是我不知道怎么描述,因为毕竟我好像也很久没有吃过这个东坡肉了,这个人不在国内,还是对故乡的很多美食有很多怀念,看我我组织一下语言,其实就是说你这个东坡肉那上面这层皮,你如果撕开它的时候。

这层皮它内部它是非常连接好,就是它它并不是一个iso topic的运动,它并不是各项同性,你如果撕开它的时候,它会整层皮一起掉下来对吧,那以我们现在的做法,就是说对于各种影响真实感的一些因素。

我们去不断的去给他,不断的去研究到底怎么样把它做得更真实,到底怎么样把它去做更真实,但是呢有没有一个很好的方法,能够一劳永逸的把真实感的题解决掉呢,那只能说现在好像好像还没有啊,好像还没有。

大家只能是对于不同的方法,用不同的simulator来得到不同的真实感,不同的完备性,并没有一个universal的一个很高很高性能,并且而且能够呃能够模拟各种材料,并且又都很真实。

这样的simulator其实是没有的,不存在这样的simulator,然后就是性能和生产力,高性能还是非常非常重要的,现在很多simulator跑一下,可能real time就别说了。

别说real time,你可能60frames per second做不到,可能60second per frame一帧60秒,有的时候都不一定能做得到啊,这个还是一个很horrible的事情。

很很糟糕的事情,也就是说你要等你的结果跑出来,你可能要等很长很长的时间,所以啊高性能计算和领域,特定编程语言和编译器其实是必不可少,是必须要做的一个事情,其他的呢包括自动的,怎么去自动的实现自适应网格。

自动的能做到多gpu多节点的simulation,分布式全自动,这个其实也很难做,我想过一段时间,这个问题其实到现在也没有一个嗯很清晰的id,怎么去做这个事情,特别是你要把它和编程语言。

和你的编译器能够结合起来,使得程序对于程序员来说,他在写一个单gpu或者单机的程序啊,这个其实还是挺难的,在这里面呢还是简单性简单性简单性,最重要重要的事情说三遍,你必须把一个东西搞得非常简单。

你才有可能去提高它的性能,如果移动已经很复杂了,你怎么去优化它呢,很难的,然后最近有两个有一些很火的研究方向,比如说learning for simulation。

就是说我搞一个神经网络去近似物理模拟器,然后下次我再搞物理模拟的时候,我就不用simulator去做了,我用这个神经网络的去evaluate。

然后另外一个叫simulation for learning,我用一个simulation去搞一个虚拟的环境,然后这个虚拟环境里面呢,大家可以去训练一些像机器人啊,各种各样的无人驾驶呀这样的啊。

任务其实就是降低实验成本,那么learning for simulation,我觉得还有一段时间的发展,你现在看这些做出来的learning for simulation,这些论文。

它其实效果说实话和真正的物理模拟器,它既不快,效果又不好呃,因为毕竟这个simulation是大家研究了偏微分方程,研究了数学各代的这个数值计算专家,然后还有,但是早期的时候。

还有提出了一些p d e的物理学家,然后研究力学的各位同仁研究了,可以说超过100年才得到了我们现在这些呃,很简单易用,并且很高性能的server,你如果真的要用一个神经网络去。

觉得可以一劳永逸的去替代它,其实还是有点难的,我觉得还是有难度的,最终能做成什么样,我也不确定,其实你可以想一想,你在比如说你就说一个m p m的一个例子,一个例子它占的空间可能是。

比如说24个byte,24个byte,然后他一个time step用的flops可能也就几百个,几百或者几千个fps,那你如果是从高性能计算角度来说,你的神经网络能用24个bt,和几百几千个flops。

能不能用这些有限的计算资源去精确的,还得很精确的,去approximate的这个物理模拟的过程,这个听起来还是挺难的,我我觉得我从一个这个,高性计算的这个角度来去说,这个其实不是那么容易实现啊。

当然这个可能有有一些呃研究这个的人,可能有一些其他的想法,这我就不是很清楚了,然后simulation for learning,我觉得这个是非常reasonable。

就是说你用一个模拟器去创造一个模拟的环境,然后让人工智能,人工智能各种a技能在里面学习,包括可微物理模呃,可微模拟环境啊,包括自动驾驶啊,各种各样的task,这个我觉得是比较靠谱的。

因为我觉得你得把simulation作为信息来源,你不能把神经网络作为信息来源对吧,这个所以我觉得simulation learning我其实个人一家之言。

我觉得simulation for learning比learning for simulation更有意思一些,ok那么接下来我自己讲一讲,我在这门课里面的收获,首先呢我最大的收获就是大家交了作业。

因为每天醒来第一件事情就是去看一看论坛,看看今天有没有同学提交新的作品,这个真的是我每天起来最开心的一件事情,因为毕竟当你去发明一个编程语言的时候,你还是希望能有人用,因为你如果像我之前说的一样。

你把编程语言搞得非常复杂,没有人能用,或许能够证明你自己很smart,但是这也只是一个呃很局限性的smart,一个真正的有智慧的人,应该做的事情是发明一个工具,使得自己的智慧能够延伸到其他人的大脑里面。

对吧,所以我每天早上看到大家写的作业,我都会非常非常的开心,也真的非常感谢能花时间去写作业的同学们,然后呢这门课啊其实我可以吹个牛,我可以说它是世界上第一次用中文开设的,物理引擎课。

这个在我觉得你可以说在人类历史上,或者在整个宇宙的历史上都是不存在的,之前都是不存在的啊,那这个你可以这个理由你可以随便出来,你可以说宇宙大爆炸以来都没有人做过这个事。

因为你很难说有另外一个种族还讲中文对吧,然后你也很难说有另外一个种族,他在他也有计算机这样的东西,也会做物理引擎,当然这个这个牛吹吹牛没意思,然后呃有超过其实有超过1000名同学参加。

这取决于你怎么定义参加了,我是把加入我们课程微信群的同学算作参加,但是你其实看这个课的播放量,到现在为止已经有3万多了,那其实如果有实讲的话,那每一讲平均下来也有将近3000次,3000人次播放对吧。

所以这个参与的人数规模上我觉得还是不错的,然后有接近50份引擎项目的提交,注意对我们的引擎项目并不是虽然交作业,但它并不是一个呃简单的小说,并不是那种填代码,写三行代码就可以提交的作业。

我们的项目是完全开放的一个项目,这也就意味着这个项目的耗时是非常长的,即使在这样的情况下,还能有50份独立完成的作业,我觉得是非常不容易的,真的非常感谢大家,那么太极在这个课程里面的贡献是什么呢。

太极的贡献主要就是我们第一次做到了计算机,统计学里面也能够复制粘贴运行,一键三连你,你你可能会觉得这个事情很难做到吗,还真的挺难做到的,为什么呢,因为以前在计算机图形学里面。

一个程序它都有很多很多的依赖,他可能依赖于open gl,可能依赖于g l e w g o f w,依赖于哥的,依赖于啊某些特别的硬件依赖于gpu对吧,你可能根本做不到这一点,那可能我写了一份程序。

我要到另外一台机器上运行,别人就会问你到底是呃你的gcc什么版本,你有什么版本的m s p c,你的gpu是什么,然后恨不得就把你的电脑复制一份过来,我才能运行对吧,那么太极做到了一个事情。

就是说一个同学写的代码,另外一个同学很容易的,就能在自己的电脑上运行,这个我觉得还是一个很有意义的事情,因为它其实加速了知识的传播,他加速了知识传播,因为一个同学写了,对于写代码的同学来说。

如果他写的代码只能自己机器上运行,别人别人别的同学跑不了他的代码,他写代码的motivation,他的动机会降低很多,如果说你写代码的时候,就知道我这个代码写出来以后,别人都能运行。

那你就有更多动力去写代码,那么对于别的同学来说,如果他知道,如果他觉得你这个战吗,复制粘贴下来以后,要配环境,配三天才能运行,那他可能就不不干这个事情了,我以前浪费过很多时间在配环境上面啊。

当然有了太极以后,至少我不说他的完全解决了这个问题,我只能说它基本上解决了这个配环境的问题,大家通过这门课lime 3201和太极,快速掌握了曾经的我折腾了好久才弄懂的知识。

我觉得这个也是一个很有意义的事情,因为呃我当时去学这些东西的时候,也没有人教我,然后也没有这些各种各样的知识,也没有太极,那我都是手写c加加,然后花了好多时间去折腾,然后很多时间调试,有很多坑。

我都是自己亲自踩了一遍哦,其实说说实话还是浪费了很多时间,但是这个还是有意义的,因为掌握这种自学能力还是非常必要的,因为毕竟这些知识这样的知识,你可能在世界上掌握,掌握到那种能教的程度的人。

可能你整个世界你找不到超过50个人,你很难找到这样的人的,而且你要找到一个能讲还能写代码,还能这个陪同学们说学逗唱的人,我觉得哈还是不容易的,然后我们也在课程里面。

第一次普及了这个m g p c t r和,m s m p m和apex相关的使用算法,这个其实呃这些名词啊,其实在国内,我觉得在我们中国的计算机科学社区里面,还是相对来说呃不是那么常见的。

大家虽然这些算法都其实非常简单有效,但是大家往往就是因为知识传播上面的原因,并没有能够很好地学习他们,ok然后另外一个感悟就是,讲课真的还是挺不容易的,因为我发现任何事情你去做它的时候。

都会比你讲的是呃设想的要好难难不少,然后因为我周一到周五还有别的事情,所以我只能周末备考,周末,每个周末都末像打仗一样,我体会出来的道理就是,原来一周只工作五天是有道理的啊,多么痛的领悟。

发了一个暑假才明白这么简单的道理,但这个也其实让我了解到了自己,工作强度的极限,所以对我来说也是一个非常有意义的事情,然后呢就是自己懂了,不见得能流利的讲出来,因为你自己搞懂了一个事情啊。

你要讲给别人听,那你需要确保别人和你有一样的背景知识,你得确保别人和你有呃一样的这个思维方式,对吧,所以其实很多时候我在讲这个课的时候,我自己也学到很多东西,因为有很多有很多东西我默认它就是对的。

很多东西我就默认他就是应该是这样,但是我要把它解释清楚,为什么这个东西是这样,然后给大家讲清楚他这个背后的逻辑是什么啊,还是挺有挑战的,就是很多东西我会发现我自己其实并没有懂啊,老实说就是说讲一门课。

我才知道自己在这方面有多无知,还是还是深有体会的,最后呢就是ltc真难用啊,这个但是呃架不住它的排版公式,排版效果还是好,然后,怎么说呢,那最后我们end up with一个混合方法。

就是讲公式的时候用雷tag,然后其他的东西就用keynote啊,这个这个也是也相当于一种探索吧,最后一个让我们哭笑不得的事情就是说呃,我并不是一个专业的搞直播人。

毕竟我大部分时间还是坐在电脑前面写代码啊,经历过这么一个课程,我的直播技术也升级了,然后学会了正确使用麦克风,有同学说诶你这个麦克风怎么用,你还不懂吗啊,其实还真不见得啊,首先你得买一个靠谱的麦克风。

我之前是用的自己笔记本的这个麦克风,然后另一个麦克风就各种噪声,然后笔记本风扇想起来的时候也会有各种noise,然后大家也会呃比较讨厌,后来我去安m总自己买了一个麦克风,我现在就用的这个麦克风。

然后呢我讲到这个课一共十讲,我讲到第八讲的时候才意识到,原来我使用的姿势是不对的,我一直在用麦克风的这个,180度的这个这个方位,然后我就想诶这个麦克风花了我四五十刀。

怎么最后这个效果跟地摊上买的五块钱的耳,机的录音效果差不多了,最后才发现原来是自己使用姿势不对,这个麦克风他是啊前后的响应是不一样的,他你得对着他的正面说,我一直都朝着他的背面说,然后背面它其实是呃。

一个其实是一个降噪的一个部分,它其实是你可以认为它0度,这个部分是对着你的,然后180度就对着观众,你他其实是目的,是为了把观众的这个噪音给它过滤掉,呃这个就是我学到了一点知识吧。

我觉得这个麦克风他设计的也有也有问题,它给人一种前后对称的暗示啊,然后使得我把这个正反面搞反了,当然归根结底还是我自己没有看文档,这怪不了人家,那么最后呀,还是要感谢一下games社区的教授和同学们。

特别是呃琉璃刚教授能把整个社区带起来,我觉得真的非常不容不容易,中国计算机统计学的社区必须要有一个社区,没有这个社区,大家就没有交流的平台,大家都自己在闭门造车,这个其实是非常浪费精力的。

然后还有闫令琪师兄,其实没有他的games 101,打下这个收视收视率的基础,我觉得可能也不会有特别的同学,特别多的同学来看我们的这个games 201,当然希望这个games 201的难度没有吓退。

各位同学呃,说实话,毕竟我也是第一次讲,然后很多地方一票心就讲的不成体系了,或者讲的太难了,这个其实第一次讲了也难以避免,还希望大家能够多多通融,然后还有周晓辉老师在浙大,其实也帮帮帮帮我们做了很多。

帮了很多忙,然后特别是几位同学,陈林浩呀,张远清呃,吴敬亭同学,然后特别是陈林浩同学,每次直播之前都给我呃发每次这个推歌的地址,然后直播完了以后会把视频上传到哔哩哔哩,包括做各种各样的后处理。

真的还是非常费时间的,然后非常感谢这边的老师和同学们,然后就是呃直接或者间接的教了我,很多在物理模拟方面的教授,然后包括讲师班,副教授,包括主播教授,然后包括呃wisconsin medicine。

就是wiscons大学百里逊分校的ftc斯帕克斯,然后ftius这个名字非常难读,然后有的时候大家会叫他f t s,但是我们还是熟了以后还是会叫他etiquetc,他给我印象最深的一点就是说嗯。

我当时申请pc的时候,我去我拿到了ef tickets offer,然后我就过去访问他,然后他居然带我去,就我和她她居然带我去吃了一顿早饭,然后吃早饭的时候,我们就坐在我还记得是一个阳光明媚的早晨。

他就开始给我讲这个呃l one cash的bandwidth,the main min bandwid要大十几倍,我当时一下子就觉得打开了新世界的大门,后来他又给我讲了一个东西。

就是说你如果没有data reuse,那你需要的memory bandwidth,比你实际有的memory bandwidth要大一百倍,后来呢我就把这个知识偷过来,然后在这边给大家讲了。

但是其实很多关于高性能计算的知识,都是ftk教给我的,然后还有就是joe terrain和run ptical rom是祖师爷了,然后joe其实是呃蒋老师的导师。

然后虽然我和他们没有太多直接的overlap,但是他们还是通过论文啊,通过各种各样的言传身教啊,使得呃相当于间接的教了我很多东西,这里我还是要感谢两位大佬的。

那最后呢就是我的博士导师shadow和beflow和bell,对我做的事情一直非常支持,基本上是在博士期间,给了我最大的做自己喜欢做的研究的自由,这个其实对一个ph d student来说。

是非常奢侈的一件事情,并不是所有的情况都是这样,有的时候你呃会因为方力的限制啊,得必须去做一些项目,然后fredo和bill一直很支持我做自己的事情,这个我觉得其实还是非常感谢的。

其实我觉得没有他们的支持,我的ph d会比现在痛苦很多,那么当然我也要感谢每一位来上课的同学,特别是交了作业的同学,基本上你如果交一份作业,那我每天早上醒来看到你的作业,我都会为了这个事情开心一整天。

太极的核心开发组artivate,然后啊旷野师兄,然后徐明宽同学,然后冯旭东呃,于鹏师兄,翟潇师兄,然后宣达呃,他们中间其实有很多是助教,然后不知道课程结束以后,有没有兴趣直接加入我们的太极开发组。

然后还有王成神的同学,然后还有kiki是一个搞cfd的一个engineer,然后还有这个塔拉利同学,中文社区,大家能看到中文文档都得益于这些同学的努力,包括方舟同学,然后同一斌同学。

然后完全就是同学李大利同学,然后王珊珊同学廖培元,然后还有罗志亚,然后这些同学的努力,使得我们才会有一个呃完善的中文文档,大家学习起来的负担才会更轻一些,还有我们后勤部的周一男同学,然后大家的杯子啊。

然后包括游记啊,都是周同学来负责的,当然最重要的还是要感谢一下,助教同学们的鼎力相助,大家能用上p l y dumper,能把太极里面的数据dump of blender和古dd里面。

包括修了很多compiler bug,然后包括实现了ti。field,然后包括能大家能够输出视频,输出gif图片到论坛上面,其实都是助教同学们花了很大精力才实现的,然后最后一点啊。

我们太极从一开始讲课的时候是版本,0。6。7,现在已经是0。6。27了,中间经过了20多个版本,然后这方面呃一定要感谢一下宇鹏师兄,每周三周六都定时的呃,为我们不厌其烦的发布新版本。

然后这才使得我们的版本能够稳定的发布,大家对版本发布有一个稳定的预期,才使得整个软件的开发能够顺利地进行下去,最后是广告时间啊,呃我这个做广告就不像其他up主一样,是需要恰饭了,我我不是需要恰饭。

我这边做广告是真的和这些教授合作过,然后呃他们真的是非常对学,非常考虑学生,学术水平有非常高的教授,然后中国教授在达特茅斯,主要是做基于物理模拟,然后计算流体力学。

然后包括一些机器学习和物理模拟的结合好,大家可以在他的主页上呢,看到他最近的研究材料,如果说大家想去做p h d读一个master,或者说呢做一个短期的intern或者visitor,都可以啊。

给朱教授直接发邮件啊,我和朱教授的overlap是他在mit做postdoc,这段时间,然后我和他其实一起做了好几个项目,他欣赏不欣赏我,我不知道,但是我我从他的身上真的学到了很多很多东西。

然后他也是一个非常考虑学生,对学生非常关心的一个教授,我觉得这个在呃学术圈,在北美的学术圈,能够像他这样这么关心学生的教授,其实是比较少的,然后啊就是我们提到很多很多次的讲师班,胡教授,然后蒋老师呃。

不但组里面再用太极来写simulation,他连自己zoom,线上开会的背景都换了一个太极图表,还可以看一看呃,当然这一页slides里面最让我吃惊的是,原来蒋老师手写写字也写的这么好。

我一直以为呃蒋老师的专长是用雷tag推公式,就发现原来这个自己,原来我的这个写字水平都比不过强老师,真的是自愧不如啊,自愧不如,然后蒋老师其实也是在做这个各种呃,emoptimization。

高性能计算啊,然后科学计算,machine learning物理模拟,然后特别是m p m相关的内容,当然最近张老师也在f e m上面有很多的进展,今年cbs有一篇学士名臣师兄啊。

他在西瓜也发了一篇非常非常有影响力的呃,f m方面的文章,蒋老师的组做的还是非常内容非常广泛,然后蒋老师也希望大家能够加入他的组,一起来开拓物理模拟的未来,有很多同学会问自己到底要不要读ph d呢。

那么这个其实也是我当时非常纠结的一个问题,这边如果要谈讨谈论这个话题,那我就又要讲上一两个小时了,毕竟这个是对于很多人来说,要不要读ph d是一个影响终身的一个决定。

那么我这边只能推荐一些资料给大家看一看,比如说偷袭hita的这个graduate study,survival guide,如何在graduate study里面幸存,那你读ph。

那你这个生活就是生存模式了,我自己读了ph以后,我就非常喜欢扫地,为什么喜欢扫地呢,因为扫地可能是我生活中唯一一个,只要去做了就能成功的事情,我可能enjoy这种只要去做了就能成功的感觉啊。

因为生活中大部分事情都是你做了,是就很小概率能成功,就是说呃有一句话叫做叫做这个怎么说,努力不一定能成功,不努力一定很轻松啊,这个是一个消极的消极的看法啊,但我我的说法就是努力不一定成功。

但是不努力一定不能成功啊,只有努力了才有概率能成功对吧,这个是一个积极的看法啊,anyway,我觉得大家还是要如果要决定读ph的话,一定要好好想一想自己是不是真的enjoy做research。

然后也可以看一看这些导师,导师们给呃大家留下来的一些宝贵的资源,好,那最后一个广告就是刘利刚,老师会在10月份到12月期间,给大家带来一份精彩的几何建模与处理的课程。

我一直对这个话题我自己也是非常感兴趣的,我觉得我到时候自己也应该去花点时间,学习一下,因为毕竟虽然我搞stimulation,但是很多时候主要用的是structured grid,就是这个方格。

然后各种geomy方面我其实是完全不懂,我相信也有很多同学会非常期待啊,这个课程这个课程定位啊,内容概要啊,前期课程啊,大家可以就看一看一看这些slides,我就不去读了。

但是我相信刘老师一定会给大家带来一门,非常非常非常非常精彩的课程,我自己也会花时间去向刘老师,学习这方面的知识,然后希望大家能够多多关注好,那么这是我们这门课的最后一张slide了。

那么首先要感谢大家坚持到这么长时间,然后呃我还是有几句最后三句话吧,第一句啊是韩愈的师说,里面说康子曰,三人行必有我师,是故,弟子不必不如师,师,不必贤于弟子,闻道有先后,术业有专攻,如是而已。

怎么说呢,我之所以能够讲这门课,并不是因为我和其他人有什么呃,本质上的不同的系统,我相信大家其实都是差不多的,我能讲这门课,只是因为我在10年前,恰好对这个话题产生了兴趣,然后花了难以想象的时间。

浪费在这个有意思的topic上面,然后我相信如果大家也像我一样,花很多时间在这个top上面,大家也可以开自己的这门课,然后我也相信三人行必有我师,我在讲课的过程,一方面大家向我学习。

我也从大家的反馈也学习到了很多东西,所以非常感谢大家呃,不管是打出来一个弹幕,不管是在论坛里面发出发一个帖子,说自己又写了什么样什么样的程序,还是在微信群里面提出问题,或者是像其他同学推荐这门课。

我觉得啊对我来说都是一个很好的反馈,我从其中真的学到了很多很多,然后闻到有先后,术业有专攻,如是而已,嗯我相信啊,每个人身上都有我们值得去学习的事情,然后我身上可能值得比较值得学习的。

是这个各种物理引擎方面的知识,但是在和大家interact的过程中,特别是很多有力学背景的同学,其实我从他们身上也学到了很多,更加专业的计算计算流体力学,固体力学方面的知识。

我觉得这方面我其实也说过很多,然后就是师傅领进门修行在个人啊,首先我不敢claim自己是大家的师傅,第二这句话听起来有点像啊,师傅在推卸责任,但是后半句话还是对的,修行在个人。

因为当你学到的知识越来越难以后,世界上能教你的人,你能找到资料是非常非常有限的,那真的就是靠你自己去钻研了,这个自学能力还是非常重要的,特别是你如果要读博士的话,呃这个自我修行,自己学习还是非常重要的。

最后呀呃我刚才提到,10年之前我写出来自己的第一个弹簧质点系统,然后其实还是很有意思的,很有意思的事情是,我在10年之后还是喜欢同样的东西,我还是在做一样的事情,所以啊我觉得是不是也有理由期待一下。

十点以后,你也可以推出一个自己的物理引擎课程呢,是不是也可以把我们的这个屋顶情的这个知识,再重复更多的人呢,那么期待10年以后你自己的无领型课程,那么我们这门课就到这里了,再次感谢大家。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GAMES201:高级物理引擎实战指南2020 - P2:Lecture 2 拉格朗日视角(1) - GAMES-Webinar - BV1ZK411H7Hc

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嗯大家好,我是胡元明,还是这个熟悉的声音,然后我是mt的3年级博士生,我在研究这个基于物理的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于物理的动画,然后今天呢我们讲讲一些简单的弹簧,质点系统和一些简单的流体,我们开始之前,我们先讲一讲这个课程里面一些logistic的东西,然后首先太极,昨天我们已经更新到了v0。6。8。

然后呃有同学反应,0。6。8呢跑一些程序的时候,由于他这个语法检查什么可能变得更严格了,然后会导致一些编译上的问题,所以如果说大家遇到一些神奇的问题的话,可以试一下,可以重新继续使用0。6。7。

两个版本差异其实不是特别大,然后同时呢我们核心开发者们也在尝试,尽快的出一个0。6。9,这样可以把0。6。8的,这个有的地方会提示编译错误的问题给他修了,然后呃作业零。

我们在波士顿时间这周六晚上十点钟的时候,我们助教开了个会,然后我们选出了一些。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选出八个非常优秀的作品,然后这些作品呢我也写了一个知乎的post呃。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

八个精致的太极小程序,大家可以去看一看,我觉得真的大家都写的非常给力,有的同学几个小时,那就把作业交上来,就感觉给人的感觉就是像座椅布置,就提交上来了,然后呢,有同学把自己领域的算法用太极实现了出来。

和我们大家一起交流,觉得这个你看看这个带绿的圆球,蓬松的网格,看起来还是非常的舒适的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有同学用太极实现了一个离散蝴蝶变换,有同学用太极实现了一个tod holy ser,但这个后面我们会讲,大家不要看到有些很神的同学,一开始就呃无师自通,自己把这些东西全部写出来了,觉得非常紧张。

但是我们后面都会讲这些细节,所以呃这边只是展示一下大家写的程序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以后面我们会讲,大家不用特别担心自己会跟不上,然后有同学用太极写了retro,这些程序呢大家都可以下载下来跑,一般也就100行代码,非常容易运行,然后也非常容易去学习里面到底是干什么。

然后有同学写了很多shader toy,这个是一个一个同学写的海面的一个shader,看起来真的波光粼粼,感觉真实感非常强,然后确实shader toy这些计算的拍摄,非常适合用太极去实践。

因为它基本上都是一个呃,按照per pixel的去做的这种这种操作,也有同学呢不但实现了shake toy,还对泰迪编系内部的工作原理,进行了刨根问底的研究啊,我们专门给他设立了一个刨根问底讲。

因为他发现一个问题,就是说太极的程序,有的时候编译起来会稍微有点慢,所以他就做了一个研究,是这个太极的编译时间,关于它程序的复杂程度到底是个什么关系,但我们也收到了这个反馈。

我们会继续去优化太极的编译器,当然啊最让人吃惊的还是这个,我们专门设计了一个叫写的好讲,因为我们发现任何词语已经难以形容,我们看到这份作业的时候的呃思想感情了,因为他真的感觉就是像课程还没讲。

然后就已经把整个课程的东西都实现出来了,当然这位同学是专业的cfd,从从业者人家是专业的嗯,之前模拟了一个叫卡门涡街的现象,就是说当你这个流体流过一个圆柱的时候,它后面会形成这些不断的在摆动了。

这些呃这些vertex或者说这些窝,然后这个很有意思,大家也可以把这个代码拿出来跑一跑,那么获奖同学呢会得到神秘课程纪念品,一个具体的我们后面会公布的是什么神秘作品,然后呃后面我们会有同学专门安排邮寄。

如果大家还想继续提交作业一样,作为零的话,我们还可以继续提交,然后我们会继续选出来一些比较好的作品,我送出礼物,那么下周呢我们会发布一个作业一,然后作业一的话呢就会和呃,它会加一些额外的限制。

因为作业零是大家自由随便写,但是作业一呢有可能会嗯会加一些,比如说必须写物理引擎啊之类的,这样的一些嗯这样的限制,但是这样的限制加了以后呢还是非常自由的,我比较喜欢自由的作业,我以前自己上学的时候。

我就不喜欢老师给我规定的各种条框框,最好就是你告诉我一个什么,然后不规定任何细节,我自己去按我自己的想法把它实现出来,然后有同学说,在python里面,就是这个python的i d l e里面。

运行太极会出现一些问题,确实是这样的,如果你用python运行会有问题,那你可以试一试用ipython,然后也可以用jupiter notebook,那jupiter notebook有一个问题在于。

你在jupiter notebook里面,print的时候会出现一个问题,你这个print,它不会帮你把太极克隆里面的print,打到你的p9 pter notebook上。

而是而是会打到你开jupyter notebook,server的一个终端,所以这个地方用起来就不是很方便,我们呃太极社区啊,都在一直非常努力的去不断的改进,当然毕竟这个课才开了呃。

目前为止才开了一奖对吧,有很多我们说非常非常多有意义的反馈,ok然后这次大家可能一共提交了几十个作业,咱们台上面,然后其实有一些很小,有几个很小很小的问题,大家只要稍微注意一下,就能比较容易的解决。

首先一个就是说代码格式的问题,这个python一般写的话,一般会我们一般会用自动格式化,然后规定一个代码格式的标准,这样的话呢大家代码格式就比较统一,然后你自己由于有自动格式化,你自己也不用去管啊。

比如说等于号左右两边有没有空格,这种头疼的事情,就可以交给自动投自动格式化去管,然后我们一般来说我们会建议用这个y a p。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

y a p f,比如说我可以随便写一个程序,呃我这边比如说写一个缩进,是两个空格的程序对吧,然后,这边我又换成了六个空格,我故意的,然后我们来把它,如果说我们用都用y a p p呢。

我们可以直接用y a p p,然后杠i,然后再加上刚才那个a点派对吧,然后,怎么回事,可以先把这个去了再说,这个是空格不符合标准吗,还是,哦不能这个地方傻了,不能用pass,pass是关键字。

我们换成一个别的,换成一个叫process,你这如果,还是跑了这个,这个python就是有的时候有点奇怪,ok如果你把这个程序喂给你的y a p f,它会自动的给你进行格式化,你看我如果输入的这个程序。

它是缩进是非常不规则的,但是如果我一旦,比如说我这边还可以再稍微复杂一点,比如说我可以加一个a等于n,然后我pass这边我可以a比如说我加两个空格,然后加四个空格等于五,如果偶尔玩pf以后。

它会自动的根据呃p1 p8 ,把我的代码进行格式化,这样大家有一个统一标准以后,读起来就会代码就会读起来非常舒服,然后交流起来也很容易,如果你希望y p f直接去modify。

你的文件就得y p f杠i,然后再加上这个a点拍,这样你再打开你的a点拍的时候,它就自动格式化好了,所以很多同学会纠结,到底是两个空格还是四个空格,然后呃要不要这个等于号左右两边有没有空格,这种好。

很头疼的问题,这些其实都不用担心,我从来不担心这些问题,这些问题都是交给y p f去处理的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok然后在论坛中贴代码,这是一个比较常见常见的一个问题,就是说这个论坛它其实是一个markdown的格式啊,一般来说我们是这样贴的,就是我们先打三个呃,这个叫backcourt。

这个这个符号在你的键盘的tab上面,e s下面,然后我们要打一个python,然后我们可以在这里面敲代码,这样的代码就会被自动的高亮,这样就非常方便,看起来也很舒服。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如说我们还是用刚才这个代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你看到它如果你加了这个很简单的三个backward,再加一个呃python,然后他就会给你自动显示成python的语法,高亮就非常的看起来非常的容易阅读,也可以,应该也可以用c加之类的啊,不行哎呦喂。

但是呢呃如果说你不加这个,那你代码就会非常打印出来,贴在论坛上了,看起来就会比较杂乱,特别是这个缩进啊,这边好像就没有了,所以大家要记得加上这个三个符号,在开始和结尾的时候加了这三个符号呢。

那你基本上你的代码的格式就会被保存了,哦对刚才说的这个好,可以换成这个cpp对,那如果是cpp的话,你可以啊打写一些c加加代码,然后他会按这个搞的,但是pon的话就一般来说大家都用python嘛。

所以就直接python就可以了,ok哦然后还有同学一个另外一个常见的问题是,大家想输出一个动画,然后发到论坛上就会非常的炫酷,这个后面这节课,后面我们会提到一些新版本的太极。

如何导出一个gift的文件上传到论坛上面,然后有些同学说呃,编译的时候,编译的时候有的时候会编译速度比较慢,那这个指的情况呢,我们有一个一个有一个option,你可以调这个ti。core。

然后点togo advice optimization,可以把这些高级的优化,它是较高级的优化,其实也是比较耗时的优化,把它关了,这样你程序编译起来相对来说就会快一点,那么今天呢我们就初步的讲一讲。

基于物质动画里面的一些基本的概念,然后说到模拟这个,基于物理动画里面的各种介质,我们就不得不谈到两个视角,一个是拉格朗日视角,一个是欧拉的视角,这个看起来啊这两个词听起来好像非常的艰深。

但是其实它非常容易理解,所谓的拉格朗日视角的,就说我们去模拟这个戒指的时候,我们想想像我们自己在这个戒指里面塞了很多,很多个随波逐流的小纸船,然后这个随波逐流脚趾船呢,它会跟着你的戒指一起移动。

由于这个小纸船往往跟着戒指一起移动,通常的你如果用拉格朗日视角去模拟这个戒,各种戒指的话,你可能会采用呃拉格朗的例子,然后或者说三角网格或者甚至用green也是可以的,只要你的。

只要你的这个节点是随着你的材料一起动的话,那你这个就是一个拉杆儿视角,那么对于拉格朗的视角里面的节点,你可以认为每一个节点,就是一个很小的一个sensor。

这个sensor去不断地检测它自己的位置和速度,欧拉视角就不一样了,欧拉视角里面放的这些sensor,它是永远都不移动的,然后你可以认为它就是一些打在水里面的木桩,然后这些桩子放在这儿。

那这些sensor他不断在检测一个什么信息呢,它检测的是如果我站在这不动的话,那么穿过我的材料,它的速度是多少,那么其实有个口诀叫做拉格朗日方法,还是随波逐流,其实你只要记住这个区别就可以了啊。

有什么sensor其实就是传感器,就是说呃你可以假设,比如说温度计就可以认为是一个sensor对吧,如果你的这个温度计,是随着你的水一起移动的话,那么呃你这个就是一个拉格朗日式的温度计。

如果你这个温度计是插在水里面,一点也不动的话,那你可以认为它是一个欧拉视角的一个温度计,这两个概念,这个概念其实拉格朗日和欧拉的视角,这个我们后面还会再提,这里呢,我们只做一个最初始的一个介绍。

那么通常来说你如果用拉格朗视角的话,你很可能就是在用这些例子,然后你用欧拉视角的话,你很可能是在用网格,但是这个是不绝对的,有有些情况下,你可能会用这个拉格朗日的三角形网格,或者拉格朗日的呃。

这个hack网格,这这这种方形的网格,这些规则网格都是有可能的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然最最常见的情况,当大家使用拉格朗日表示的时候,大家使用各种各样的例子,然后左边呢我们展示的是一个呃,基于position based dynamics,这个叫基于位置的动力学的模拟。

你看它这个是一个各种各样的例子,通过各种方式给它连接起来对吧,然后呃他这个例子可以表示降落伞的绳子,可以表示降落伞上面的,这个降落伞上面其实拴的是一个兔子啊,大家可以看到呃,图形学里面。

大家很喜欢用斯坦福三维扫描出来的这个兔子,来作为各种各样的例子,这边可能看的不太清楚,然后你可以用来用这个粒子来模拟水,这个可以它可以用来模拟各种各样的东西,然后右边呢是一个典型的欧拉表示的烟雾模拟。

然后这个里面呢,其实就是一般是用一个背景的网格,然后网格上的每一个点,表示的是穿过这个点的流体的速度,那左边的这个左边的这个基于粒子的模拟呢,它的每一个例子表示的是这个例子,它会呃这个例子会携带什么的。

会携带它自己的速度和位置,所以呃一个常见的问题就是,欧拉的网格里面的每个点我们是不记他的位置,因为它位置很容易算出来对吧,因为你可以根据它的i j k下标,然后乘上一个调查x。

你就知道这个网格的格点的位置是在什么地方,但是拉格朗日的例子里面的,我们会在例子上面额外的记一个位置,因为这个例子会随着你的被模拟的戒指,去不断地移动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那今天我们主要讲两个东西,一个叫做max ring system,就是这个弹簧质点系统,另外一个是s p h,后面我们会提到,那么这个弹簧质点系统呢,是一个非常非常简单的模型,但是它非常非常的有用。

它可以模拟很多很多有意思的东西,你可以用它来模拟布料,可以用它来模拟头发,可以用它来模拟这个弹性的呃,各种弹性的材料,比如说这边是一个可以看到有一只小狗,它被非常残忍的用弹簧质点模型表示出来。

然后被定在了呃,有有几个点把它固定在了空间中,然后呢,如果你用弹簧质点模型来模拟布料的话,那你就是相当于用很多很多的弹簧,把一些点给它连起来,然后你怎么连接这个弹簧,其实就决定了你的布料的性质啊。

这个地方,这个右边这张图展示的是一个比较基础的,这个弹簧质点模型来表示不了,然后这个里面的每一个红点就是一个支点,每一个呃每一条白色的这个线呢就是一根弹簧,然后这个其实非常不理解。

我觉得大家小时候应该都玩过弹簧对吧,后面我们会给出更数学一些的表述,这个弹簧质点模型啊,在游戏里面非常有用,我小时候就玩过一个游戏,叫做战争世界,然后这个游戏呢是让你用弹簧质点模型呃。

通过不断给它把它们连接起来,然后来呃搭起一个桥之类的,好像我记得当时是要达到一个目的地,还是越搭越高越,它有一个模式是让你达到一个目的,有一个模式是让你越打越高啊,但是呃你搭的高了以后呢。

由于你这个呃它下面的这个弹簧,它受的力就会越来越大,所以一定要保持那么理性啊,并不容易,还是一个挺有意思的游戏,最近又有一个游戏呃,我自己其实没玩过了,他就是其实你看也可以认为。

它是一个比较简单的弹簧质点模型,然后它的里面的物理呢是这样,就是说你嗯有一些不锈钢的这个材料,然后你把它不断连起来,然后使得你的车呢能够从左边,顺利的开到右边去,这游戏我看网上很多视频好像还挺有意思。

但是一直没有找到时间去玩一下,但是我小时候好像玩过很多类似这样的游戏,ok那么刚才我们简单的介绍了一下,弹簧质点模型,下面呢我们来讲一讲它内部的一些数学的原理。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

哦对我应该先展示一下我昨天临时写的这个demo。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

啊这个就是一个简单的弹簧质点模型,然后这个代码呢已经发在论坛上了,大家如果迫不及待的想跑他的话,也可以去下载下来跑一跑,这个demo里面有几个按键,比如说你可以按住空格把它暂停。

对这个demo可能需要0。6。8,大家可能得更新一下,然后你如果再按一下空格,它就会恢复运行,这个里面有两有两个参数非常重要,一个是弹簧的stiffness,就是它的这个硬度。

你可以把它stevens调大以后,你整个材料就会变得这个坚如磐石,非常的坚硬,我们这边来随便画一个网格什么的,然后我们可以把step调小,这个stiffness,其实就是你可以认为是呃。

类似young modulus的一个杨氏模量,然后它决定了你这个弹簧有多硬。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我们可以把这个steps给他,哎呦啊,刚才我成功的展示了一下,显示时间积分怎么怎么爆炸,我过会儿后面会讲到这个,为什么刚才会出现那种爆炸的现象,那这边呢我们把它我我应该是把它调软一下。

嗯我发现这个mac os x上面好像shift不work,anyway,如果大家是在用windows或者在用linux的话,你如果按shift加s的话,你可以把这个系统调的更软一点。

这个程序是我在linux上面写的,所以我之前没有发现这个问题,anyway,然后还有一个可以调参数是dumping,现在这个单品是比较小的,我可以把这个单位调大一点电,并调大了以后。

你会发现一切好像变得非常灵,然后这边我加的是一个非常简单粗暴的,直接给速度上面加了一个指数衰减,然后如果把电力调小了以后,嗯你的东西,你的这个物体它就会运行的更加灵活,如果dp大了,它就会显得非常廉滞。

很多游戏里面其实喜欢把产品搞得比较大,因为他不希望这个东西一直在不停的摆动,我其实可以演示一下,如果说嗯如果说我把这个dp调小一点,嗯我可能得现场改一下代码吧,不好意思,比如说我把这个用e。

用e来表示弹簧变得更更加柔软,你看我如果按了e的话,我会把它我的steps除以1。1,然后d呢呃d默认是应该提高单品对吧,然后,我们再加一个按键,比如说这个w我让w去减少点平。

ok ok现在应该welcome啊,我刚才一直想演示一下这个弹簧质点系统,如果stents比较小是个什么样的体验,我们现在来展示一下现在的这个step,你可以看到的是1万对吧,我可以把它调小一点。

不断再调小一点,它就会啊整个就蔫了,就不能支持重力,我可以把它再可以再把它调大,又不是,嗯我看一下刚才是应该是s监视o有点点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我把它调的比较比较硬,然后w是调的比较软,ok嗯这个是一个挺挺好的,能够展示stephens的作用的一个结构,这个弹簧质点系统啊,你如果有的时候你把它先调得非常软,然后你再把它调的非常硬。

它不见得能恢复原来的形状,它有的时候就会形状就会卡在一起,我们也可以把这个单p调的非常小,现在单p是20,我把它调到一个很小的很小的值,单品小了以后啊,你这个整个系统就会像一个果冻一样。

它会不停的不停的晃动,但是你如果单p调非常大,那你这个damping就得想想办法,让它不要让一些平移的运动也受到单品啊,我这个单品加的比较弱智,它就是一个基于速度的嗯,指数衰减的单品。

很多时候大家单品是加在弹簧上面,给弹簧加单品,今天由于这个程序为了大家学起来方便,所以我们用了一个非常简单的点评modek,那么刚才演示了弹簧质检模型,运行起来是个什么效果。

那这边呢我们就给出一些数学公式,其实它还是非常简单的,大家不要被这个公式下到它,其实就是说白了就两个东西,胡克定律和牛顿第二定律对吧,我们先看一下胡克定律,胡克定律它这边是在做什么呢。

你可以看到它是呃i到j的这个受力,它是什么,它是k这边是呃弹簧的stiffness,然后你要乘上现在两个质点的两个质点,它们的距离减去弹簧的静止距离的,做一个差。

然后呢你这个你前面算出来这个是个标量对吧,那你得再乘上一个单位的向量,这个单位向量应该是什么呢,两个点之间的力应该是从x,是从这个i指向j的,然后我们把它乘起来,就得到了两个质点之间的手笔。

然后对于其中的一个支点,我们得算他所有的相邻的例子对吧,我们把它这个力再求和,就得到了质点i受到了所有的外力,当然这边还有一个重力呃,知重力我这边没有写出来,那么有了力,我们就可以根据牛顿第二定律对吧。

f等于a那么a等于f除以m,所以我们就得到速度导数呢是力除以它的质量,或者大家有的时候会在simulation里面,会经常写质量的质量的倒数承受力,因为在simulator里面。

在这个计算里面乘法比除法要更加的廉价一点,所以大家一般会把质量先提前取一个倒数,然后需要用的时候再把它们乘起来,然后接下来最后一行,那就更简单了,那其实就是这个位置的导数等于速度对吧,这个其实非常简单。

那么讲了这么多以后啊,其实我们下面我们来看一看,这个时间积分是怎么做的,我们刚才讲到我们刚才的这个例子,它是一个呃我们写出来的方程全部都是连续的,相相当于是一坨这个常规的方程对吧。

那么我们如果要在计算机中表示,就遇到一个问题,要有什么问题,计算机里面的时间全部都是离散的,计算机有用的计算资源也全是离散的,你不可能说呃,我取一个无穷小的一个时间为单位,来记录了系统。

那大家一般这个时候会怎么办呢,大家会取一个delta t这个调查器,一般来说呀呃比如说你可以是一个比较小的值,什么十的-3次方啊,十的-4次方,这个一般会根据你的嗯,物理系统的各种参数来取一个。

一般来说大家会喜欢选一个比较大的例题对吧,如果你dott比较大,那就是说你模拟同样长时间的物理过程,你跑得就比较快,所以调查进了一般认为是会越大会越好,当然这个调查题大了以后。

又会有很多的不稳定性的问题,这个我们后面会提到,那么有了这个,那么我们做了这个离散化以后,我们的v就不再是连续的连续的b了,这个b我们就给它加一个下标,这个下标是什么意思呢,这个vt就表示t时刻的v。

然后v t加一呢就是下一个时间不等v,那做了这么个操作以后,你其实就很容易知道呃,如果我们用这个比较简单的前向欧拉法啊,所谓前向欧拉法,就是我们根据现有的状态来推测,直接推测以后的状态。

那么你可以得到这么个简单的公式,那就是说你的下一步的v等于什么,等于这一步的v加上呃,deltt乘上你这一步的exciation对吧,这个应该很容易理解,然后呢对于x我们用同样的方法来处理。

是x一加一等于x t加上,掉下t乘上v时刻的速度,因为他们呃v是x的导数,所以我们其实向前累进了一步,那么这个forward oiler大家用的其实比较少了,大家一般用的比较多的是这个sei。

implicit oiler,或者有的时候叫大家叫做它叫做simplily oiler,然后他也是另外一个呃,根据现有状态就可以推出,推测出未来的一种时间计算方式,你可以你可以看到一和二。

这个forward oor和semtorder有什么区别呢,唯一的一个区别就在于这个公式,它的右下角这边呃,for oiler用的是t时间的速度,但是seven trc它用的是t加一时间的速度啊。

这个看起来是个非常非常小的差别,但是其实很多时候嗯他是一个呃,它会有一个本质的准确性上面提升,然后他之所以有的时候叫做simactive order,是因为它有一些守恒的性质,然后他向他呃。

它是在一个寒冰偷练系统里面,来做了这么一个理论分析,那么更高级一点呢,有的时候大家会用backward oiler,然后通常backer会和流动的,然后把结合在一起啊。

这样它就变成了一个implicit,一个系系统,这个后面我们会继续讨论,在此这边呢大家只要记得这个sein,sein place in order就行了,就是这么第二个这两个公式其实非常简单。

就是你假设调查t之类,这个v和x都是常数对吧,那你朝前呃,匀速直线运动嘛,这个应该还是比较容易理解的,那么呃用这个synthetic oiler来实现max min system嘛,其实非常容易呃。

其实就这么三步,你首先得计算一下你的新的速度对吧,然后计算新的速度以后,你和地面做一次碰撞,然后呃你用新的速度来计算一下新的位置,如果你去看他代码呀,其实就这么可能,20行代码。

这个是一个subs step,这个ero这个kneel表示,把你的simulation朝前推进一步,那么大,为什么这个地方叫subs step呢,因为一般来说你呃做simulation的时候。

你的time step size,不会和你实际上展示出来time step是一样的,因为你如果玩游戏的话,你的帧率是多少,是一般是呃60f p s对吧,如果做电影的话呢,一般是24fps。

那么你在游戏和电影里面,那帧与帧之间的间隔,或者说这个step size一般就是1÷60,或者1÷24,那么但是在模拟里面,很多时候你的time step取不到这么大的数值。

你可能只能取一个非常非常小的数值,那怎么办呢,我们把这么一针分成若干个substep,然后在每个sub step里面再用sim lc oiler来做,ok那么我们可以看这个是这个subsekernel。

其实非常非常简单,他做什么事呢,啊,我们它对于,首先它有一个n平方的一个破循环对吧,他先把呃所有的i枚举一遍,先做一下dping,然后我们计算呃总的受力,总的受力呢首先我们要算一下呃。

他的g等于mg对吧,这个是重力乘上particle的质量,然后我们再去枚举一下,其余的所有的呃,所有的例子,看他们之间是不是有联系,这边我用residence,如果是residents是零的话。

就表示这两个之间没有弹簧,如果residents不为零的话,表示他们之间有一个弹簧,然后呢,我们按照胡克定律的公式来算一下,这个例子的受力,然后我把力算出来了,算完了以后,我们用力来更新速度。

这个其实就是simply simplex oiler的第一步,然后接下来呢我们和地面做一次碰撞,为什么在中间和地面做一次碰撞呢,这个其实也是有学问的,如果说你在呃计算速度以后再和地面做碰撞。

有可能你这计算速度的时候,你的速度的有啊,你速度的,比如说你和速度的y component可能还是负的,那你的这个例子就会陷到地底下去啊,那这个看起来就不是很自然了。

所以我们呃一般来说会是在对于弹簧质点系统,我们会是在计算完力和速度以后,立刻和地面做一次碰撞,因为这个时候如果你发现它一旦有线到地底,地底下的趋向,你就可以立刻把它的速度的y component设成零。

那么接下来呢我们就很容易,我们直接把速度累加到他的位置上面去,就可以计算这个新的位置,那么刚才提到呃,cpc oa是一个显示的时间计分器,那还有很多影视的时间计分器,它们有什么区别呢。

我这边就简单的介绍一下它们的区别,后面在这门课里面,我们会讲到很多很多这样的计分析,然后呃会有很多很多的低调,但是如果一次讲的话,那大家肯定会听的比较无聊,所以我们今天就讲一些比较初步的东西。

那首先什么叫显示计分器,显示计分器啊,它的一大特点就是未来的状态嗯,只依赖于过去的状态对吧,那它就非常非常容易实现,因为你整个就是一整个程序,就是一个递推对吧,你从后面时间呃。

以前的时间直接推推到未来的时间嗯,显示计分器有很多种,然后有这个follow ur和和symatic oria,我们之前讲过,然后还有一些更高阶的显示向前的计算器。

比如说像2k2 k22 k32 k4 ,然后他们的数值精度就会更高一些,前置事件进风器有一个特点啊,这个不是一个特别好的特点,就是它非常容易爆炸,那什么叫爆炸呢,我刚才其实已经演示过了,这边有个公式啊。

就是说你的交叉t必须小于等于根号下,m除以k这个这个公式你看可以看出来,当一个粒子的质量变得越来越大的时候,它能够允许的调查t就会变大,但如果粒子质量变得非常小的时候呢,它的调查t就会限制就会更近。

也就是说允许调查t就会变小,呃相反了,如果这个例子,如果这个弹簧,它的k这个这个进度越来越大的时候,那你调大器允许的越大,气也会越来越小,所以说它对于特别硬的材料,其实并不是特别适合。

这边我可以演示一下,记住这个公式啊,这个是dott小于等于根号下m除以k,那在我们刚才那个例子里面,m是一,然后第2t是十的-3次方,那么你可以推断出来这个我们允许的这个k啊,大概就是十的六次方。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么我们接下来演示一下这个爆炸是个怎么,是个什么状况,我们先随便画一个几何体,那么你可以看到呃,我们现在这个stevens是这个十是1万对吧,我们刚才推算出来十的六次方。

也就是说在你的stens在接近100万的时候,他就会这有一个爆炸的倾向,那我们来把它调得更硬一些,可以看到这个系统,现在已经弹簧已经变得越来越硬了,好注意,现在我们已经有50万了。

那么接下来我每按一下我键盘上这个s键,就是让它弹簧变得更硬的键,它都有可能会爆炸,我猜可能未来啊哈哈这个果不浅啊,不幸严重,你只要呃我估计这个是这个值,大概就是一个临界点,你接近这个值呃。

其实我们刚才预测出来的是100万对吧,现在60万其实也差不多,这个前面有一个常数,你可以看到他这个,他现在是在一个勉强稳定的这么个状态,可能有些时候还能勉强保持稳定,你如果一不小心它就挂了。

但是呢你如果呃把它再稍微减小一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如说减到捡到一个临界值以下呢,它基本上就不会发生爆炸的事情,啊也会涨啊,反正这个临界值有的时候它不一定是,一个非黑即白的,有的时候啊你靠近了以后,他只会会在一些特定的配置底下会出现问题。

因为我们刚才说的,这个k和m其实都是一些近似的,取得一些有代表性的值,那么这个公式,其实刚才有同学说这个公式怎么推出来的,其实你可以算一算呃,他这个振动周期,因为弹簧的这个omega是等于什么。

等于根号下m除以k对吧,然后啊k除以根号下k除以m,然后所以你这个地方基本上这个直觉就是说,如果说你在一个time step里面,你的这个系统本来应该震荡呃一个周期。

但是你现在没有完全的captured,你可能比如说这个震荡了两个周期,但是你只有一个time step,这种情况下,那往往就会出现问题,这个是一个比较直观的理解,当然也有严格的推理的方法。

就是这个follow er和synthetic oiler,你是可以啊,用一些,矩阵密的方法来分析它的数值稳定性了,然后这个就大家可以去看各种文献,然后这个在数值分析里面,很容易找到这样的内容。

那么刚才讲了显示时间计算器,很多时候大家会用影视时间计算器,比如说后向无拉或者终点法,这个终点法我们后面会讲到,那么后这个为什么叫它影视时间计分器呢,因为它有一个特点,就是说你的未来不止依赖于你的过去。

还依赖于你的未来啊,这个就有的时候像一个这个相机生蛋,蛋生鸡的问题,那你为了解决这个问题,你就得去解一个线性系统对吧,因为你的未知数会依赖于你的未知数,所以它就是一个非常复杂的一个信息系统。

那通常情况下来说,implicit这个sober它是更难以去实现的,那么在一个implicit over的一个time step里面,它的每一个step会更加的昂贵,但是它有什么好处。

他的step能够容忍的time sap就会变大,嗯有的时候这个会给你一些好处,有的时候他不见得给你带来很多好处,有很多同学觉得in place is over是不是一定就好,那倒也不一定对吧。

他嗯首先它有一个很大的缺点,就是难以实现,然后难以实现的话,那就说明它难以优化,难以优化,那你就做不了各种很复杂的底,在计算机底层的这些优化,比如说你想想做向量化呀。

想做在gpu上面用各种呃学的marry啊,各种各样的优化,那你如果写程序非常复杂的话,就很难去优化它,所以复杂其实是in place is over,的一个很大的一个问题,那么另外一个问题呢。

就是说由于他的每一个time step变得更expensive呃,有的时候你得去衡量它,这个呃到底是他的time sap变得更大了,给你带来加速更多,还是每一个time变得更加昂贵了,天天来的加速啊。

给你给你这个加速的反作用来的更多,这个他们两个就会fight against each other,会互相的打架,那你得去看一下到底哪一个方面更胜出,然后这样这样就决定了。

他这个server是到底是从变成licon,到底是变快还是变慢了,然后他还有一个问题呢,ap server有的时候会给你带来额外的neral damping,甚至会出现一些locking的问题。

这个所谓locking locking呢,就是说呃比如说你用有限元去模拟一个衣服,你会发现当你的衣服非常safe的时候,他有的时候啊,这个衣服他就会你如果用in place is over。

他再加上各种dumping的这个问题,那他这个衣服就会变得像一块石头一样,那没有人想去穿一个非常坚硬的衣服,对吧啊,所以rsa在很多时候呃有它的好处,但是也有它的joy,也有它的坏处。

那么我们现在来讲一讲弹簧质点系统,它的implicit time integration应该是什么样子,那么这个这个应该是一个bl oor的描述啊,首先我们来看我们这边有公式一和公式二,公式一是什么呢。

我们假设还是和之前一样,我们假设这个时间段内,它的速度是一个恒定的对吧,那你可以看到公式一里面嗯,它它它的xt加一依赖于v t加一公式二,公式二说什么公式二就是说我这一个时间段的。

我下一个时间段的速度等于什么,等于上一个时间段的上一个时间点的速度,加上delta t乘上这个时间段内的加速度,但你看这个加速度它用的是xt加一时候的force,也就是说啊一依赖于二,二又依赖于一。

那怎么办,我们可以解一下这个先做一步化简,把他们把这个一带入到二里面对吧,那你就可以看到得到了这么个公式三,公式三是什么呢,呃vt加一等于v t加上dt乘上m的逆啊,这个m的m矩阵是什么。

m矩阵是质量矩阵对吧,其实这边就是f等于a那么a等于什么,a等于m的逆乘上f,这边我们其实把所有的呃粒子的x都拍平了,变成了一个单独的向量,比如说如果我们有n个例子,那么x其实是一个3n维度的向量。

为什么呢,因为它每个粒子有x y z对吧,我们是假设在三维里面xyz,然后我们把它拍平了,这样就得到一个3n为多差,但如果你是二维的话,那你的这个x就是2n长度就是2n,那你的v长度也是2n。

那么从三到这一步,你会发现它是一个非线性的方程,为什么是非线性的,因为呃,你现在很显然你的未知数是vt加一对吧,因为你的vt和xt都是知道的,那这个非线性来自哪的,来自于这个f。

因为你的f它是一个往往是一个非线性的函数,那么怎么办呢,呃这个后面一般来说大家会采用的,下一步的搞法,就是说我们搞一波流论,我们把这个f在xt点处泰勒展开一次,泰勒展开一阶。

那么我们就可以把这个f xt加上dt的t,b t加一,给它展开是什么,给它展开成f x t加上f对于t的它的这勾边,然后在xt处的求职,然后呃乘上掉下t再乘上bt加一。

那么这个其实就是一个一阶泰勒展开对吧,那么公式四就是一个展开以后的公式,或者说我们叫这一步叫线性化,因为你做了这个操作以后,你整个系统就变成线性了,因为你这个地方啊,这个偏f偏x是一个线性系统。

是一个勾变对吧,ok那么我们把四搬过来到这边变成五了,那么我们做一下整理,稍微整理一下,其实就是做一下移项了,那么你就可以得到啊,它是一个这么个公式,就是说i减去掉到d平方乘上m的力,再乘上结构变呃。

这个整个是一个线性系统,然后这个系统呢扯上bt呃,加上bt加一等于bt,加上掉到t乘上n e f x t,这是一个非常非常nice的线性系统,然后那么我们怎么来解它呢,这个解线性系统啊。

在物理里面是一个呃,在物理模拟里面是一个非常非常重要的问题,有各种各样的方式来解线性系统,今天呢我们就由于时间关系,我们就介绍一个最简单的方式,就是夹克比迭代,那么除了价格比迭代呢,还有高材料迭代。

然后还有共轭梯度,共轭梯度里面花样就多了,你可以加各种各样的嗯,加各种各样的这个preconditioner,你可以跟我梯度本身还有各种变种,比如说如果你的系统是对称正定的,你就可以直接用共轭梯度。

但是如果有的系统它不对称,那它真有的系统呢它对称不正定,那就有各种共轭梯度的变种,这些server一般统称quite of subspace server,后面我们会专门有一讲。

介绍怎么用quite of subspace server来解线性系统,ok那么我们再整理一步呃,我们再把它写清楚一点,其实就得到了这么个东西嗯,a等于a减去这么一坨。

然后b等于a v t加上后面就是它的加速度,乘上掉它t对吧,那么你可以看到我们现在经过这样的一些整理,我们其实已经得到一个很经典的一个表述的,就是ax等于b,那这个这个是a b t加一等于b。

我们要解的是bt加一,怎么解这样的一个信息系统,调解这个线性系统啊,其实也非常容易啊,这边是一个太极的demo,这个是一个夹克比迭代法,所以这个夹克比迭代法在干啥呢,它的作用就是说我们每一次迭代。

我们啊都把未知数的一项换成一个值,这个值啊能够使得你如果只看他这一一行的话,它的右端项能够被满足啊,这个说起来有点绕,但是其实你如果看代码的话,其实非常容易,那这是单独的一部夹克比迭代代码其实非常短。

只有十几行对吧,如果说呃大家有兴趣的话,可以跑一跑诶,对我其实我就可以跑一跑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

呃这个biteration你可以看到我这边创建了一个,20x20的矩阵a然后有个位数x,然后有一个6x,然后有一个b b就是我们的右转向,然后每次迭代呢就是这么一个kernel,这个叫iterate。

然后除了迭代,我们有的时候还需要算一下residual对吧,你得算一下它的嗯,ax是b减去a x叫做residual,然后算了个recedure l too long,这边是,然后我们初始化矩阵。

然后我们就可以算了,这个程序大家可以跑一跑,你可以看到呀,我们一开始的时候residual非常大,经过若干次迭代呢,这个residual迅速的就变得非常小,但是这个收敛速度还算比较慢的。

如果你用共轭梯度的话,用根本用不了这么多这么多次迭代啊,这边只是为了图简单,搞了一个比较简单的夹克比迭代。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么这个算法他的直觉是什么呢,他的直觉就是说我每次都更新一下我的x,使得这个x能够把我这个矩阵的这么一行,或者其中的一个线性方程组可满足,但是你每次做这种更新,也不见得他就每个都满足对吧。

因为你每个更新都是局部的,而且呃你改了这个x以后,你可能修了这一行,下一行挂了,然后修了第二行,第三行又挂了,所以这个要迭代很多很多次,然后不断的才会收敛到一个值,他也不是总是收敛的。

他只会对一些呃性质比较好的矩阵那个收敛,也就是说他的谱半径得有一些要求,然后今天我们就不讲,今天我们就讲一个呃,怎么去实现,他用太极实现它这么一个非常简单的一个概念,后面我们会讲更多关于线性系统。

怎么去sop的方法,那么刚才看了这么一个复杂的公式,其实你会发现,如果说我们给这个公式里面加入一个数,叫做贝塔,那么我们其实就可以嗯,把forward和backward oiler给它整合到一起。

不好意思,这个三这个地方应该是贝塔等于一,这边有一个type,然后如果说我们贝塔等于零,那我们得到的是一个什么样的系统,如果贝塔等于零的话,那么左边v左边这个一整项它其实,就是单位矩阵对吧。

因为你这个是零,那其实就是一个单位矩阵,那你就可以直接把它消了,那你就得到v t加一对,v t加上这样的一个呃公式,那么相当于他就是一个一个显示的,选项的积分器,如果你贝塔等于1/2呢。

那你能够得到一个终点法,重点法它可能比ba在数字经路上,有些情况下会好一点,如果你贝塔等于一呢,贝塔等于一的话,让大家脑补一下,这个地方是一啊,那其实就是刚才那个公式,哦这边有同学问为什么不直接求逆啊。

这是一个很好的问题嗯,解矩阵的时候,很多时候会呃直接去求举个例,然后把这个因为我们这边看到这边是呃,a b t加一等于b对吧,那你其实有个公式,就是bt加一等于a的逆乘上b。

那么求取能力啊是一个非常昂贵的操作,在矩阵比较小的时候,你求你还还可以求求这个就比较省事啊,如果说矩阵非常大的话,你求这个力矩阵很多时候矩阵都存不下,为什么呢,因为你这个a啊往往是一个稀疏矩阵。

这个我们后面会提到,但它的力呢就不一定是个稀疏矩阵,它这个a它的力可能变成一个重密矩阵,那你的内存就存不下,那么呃还有一些别的方法,比如说去呃,不求你,我们去直接用一些呃直接解法。

比如说pardl这个direct solver,也可以去求这样的系数,线性系统,其实在如果你有party sol的话,用partial解这个系统的话还是挺省事的,那么这边我们就不多讲了。

后面我们会提到各种解线性系统的方法,这边迭代法因为比较容易在太极里面实现,所以我这边就讲了一下迭代法,啊刚才就有同学问,其实就是在解,我们其实已经提前讲过这一页的这个东西,如果说我们有成千上万个弹簧。

成千上万个支点,那怎么办,这个时候我们就得使用呃,重使用这个稀疏矩阵,然后可能得使用一下共轭梯度,还得做各种各样的预条件preconditioning,然后还得做一些呃物理模型上面的。

在精度和速度上的取舍,比如说你可以用基于位置的物理对吧,这个p p t,然后呢也有一些完全不同的,解决这个发动我这个弹簧支点问题的方法,比如说呃有一篇很有名的paper。

叫做fast simulation of mass brain system,这个是一个非常好的paper,然后它里面其实就用了一个不同的formulation,让这个问题solve的更快了。

大家有兴趣的话可以作为扩展阅读去看一看,ok那么我们刚才讲了弹簧质点模型,这边呢,呃接下来我们讲一讲smooth particle haynamics,就是这个呃拉格朗日法的这个呃。

解流体力学的一个一个方法,这个smooth party还是dx,一般大家叫s p h,这个s p h呢它的高层的idea是什么呢,就是我们用一坨粒子,然后每个例子呢上面携带一些物理量。

然后再用一个核函数去呃近似一个连续的长,然后这边这个公式啊其实它也非常直观对吧,那就是说在x这一点,它的这个物理这个场的值等于什么呢,我去给周围求个和,然后求和的时候。

用这个核函数去加权平均我周围的例子,然后呃这个其实严格来说不是,并不是一个加权平均啊,这边只是直观来说,它其实就是做了一个类似于smoothing的,把它周围的例子给它光滑了一下,怎么个操作。

然后这个核函数呢它是中间大两边小,所以它可以让接近这一个点的例子贡献更多,然后远离这个点的粒子空间更小,当你的粒子特别远超过一定的范围,比如说超过h h就是和这个核函数的这个啊support。

或者叫做它的半径,超过它的半径以后呢,贡献就是零了,那么这个地方a可以是呃,几乎任何随着空间变化的物理物理量,比如说可以是你的速度,可以是你的density对吧,可以是treasure。

当然你如果要求导数的时候,那这个就完全是一个不同的故事,后面我们会提到,那么这个s b a这个方法,一开始的时候是用来求天理物理,然后他有什么好处呢,它有一个最大好处就是它不需要mesh。

它非常非常适合用来模拟啊,自由表面流体,什么叫自由表面流体呢,就是说呃比如说你有一盆水,然后这个水有一个水和空气的界面对吧,那这种它有个自由自由表面,我们就叫它自由表面的流体。

那什么样不是自由表面流体呢,比如说你做一个烟雾模拟,那它就不是地表面雾模拟对吧,因为你的这个呃不管你有没有烟,你都是有空气对吧,所以啊它整个空间都是被填满的,所以烟雾玻璃就不算作自由表面玻璃。

所以很少比较少有人用s p h来做烟雾模拟的,因为你用sp制作烟雾模拟,你得把整个空间全部粒子填满,那这个有的时候嗯就比较coser,那么相比于其他的把空间填满的模型,比如说grade。

那这个particle overhead还是比great的要高一些,所以大家一般情况下如果要做烟的话呢,一般就是用一个background grade来去表示背景的速度,长呃。

我觉得s p h还有一个很大的好处,就是它直观上面非常非常容易理解,你就可以理解成每一个例子是一个呃一小包水,那当然是严格来讲它并不是这个case,但是你这么一开始这么理解,其实也没有什么问题。

那么用s p h言来模拟流体,其实最简单最简单的方法呃,叫做wc s p h,weekly compressed by s p h,它不是大家都知道水它其实是不可压缩的对吧,但是呃你要实现不可压缩的。

其实是要下一番功夫的,所以一般情况下大家会做一些呃,如果说入门的时候会做一个可压缩的流体模拟,那么关于这个流体模呃,这个weekly compressor s p h,它最关键的其实就这么一个公式。

就是v对t的导数啊,这个d是材料导数,你就可以认为是粒子呃,某某一个s ph的例子,关于时间的导数,这个为什么用这个d大地,而不是用小弟或者用或者partial,这个我们后面会下一讲。

我们会提到他这个叫做材料导数,这个材料导入非常confusing,他有好多好多的名字,它可以叫material divity,derivative,可以叫lagroni divity。

可以叫这个convective derivative,然后或者叫vection dury,有好多好多名字啊,大家只要记得这个大地是表示跟着粒子动的,这么一个导数就可以了,嗯然后它的速度的导数是什么呢。

那么首先你液体里面都有个压强对吧,那你的压强的梯度,就会影响这个流体的这个粒子的速度,但你当然你得把它除掉呃,压强梯度得出一个密度对吧,才得到它的加速度,那么左边呢是流体的内力,那么加号右边就是重力。

就是流体受到的外力,但这个记忆一般来说,有的时候大家会用它的指重力,有的时候大家就图省事,各种各样的外力都把它算成g,那么压强是什么呢,刚才我们提到ph,可以用来近似表示流体在某一点的密度对吧。

那么一般来说呢,这边压强如果在wc s ph里面,就用用一个叫做呃equation of states,的方法来表示压强,那这个压强还有这么个公式,就是压强等于b这个b是box modules b。

然后再乘上roll除以rolling,rolling是一个理想的一个密度,那么roll除以roll 0的ga次方减掉一,那么呃你可以看到直观上来说,如果说肉非常大,那你这个p就会非常高。

那你就会压强很高,压强很高呢,它就会推着周围粒子离开自己,相当于他在尝试保持自己的体积,呃然后呃wb c s p h还是用这种经典的ax,是用这些东西来近似的,然后roi呢是这么个表示方式。

基本上所有的s p h里面的ro呃,每一个例子上面的肉,都是通过它的周围粒子的质量来加权得到的,当然你如果去仔细读w c e s p h这篇paper的话,它里面还讲到各种各样的扩展。

比如说怎么去加表面张力,怎么样去给它加联系,然后一个非常非常好的tutorial s ph tutorph,tutorial是这个uh s ph technics for呃,g物理动画。

在呃流体和固体里面,这个大家可以去打开来看一下,它是一个网站,然后上面是现在最懂s p h的一帮人,在图形学里面最懂p h的一帮人做了一个教程,非常非常的好。

然后大家如果去看这个w cs ph paper里面,你会发现它的导数用的是小d,那么用小d在这种情况下就有一点呃起义,一般来说我们会用大地啊,小弟,它这个导数就给人感觉是一个全微分的感觉。

这个感觉就呃非常的confusing,一般来说在particle里面,我们会用大理表示它的物质导数,就大家不要被这个文章里面的,有一个符号给误导,刚才提到了,我们可以用这个ax m公式来去。

在每一个粒子处,计算出这个粒子所在的这个位置,它的物理量的值是多少对吧,那很多时候我们需要算它的梯度,算梯度怎么办呢,比如说我们刚才就有一个呃这个压强企图,这个grad p那么算梯度啊。

我s p h里面有一套理论,然后呃他算梯度有一个特别的算符,这个算符长的是这样,看起来看起来好像很奇怪,然后你仔细去推呢,你会发现,他其实并不能按照从上面这个推出来,然后它的值这个下面这个梯度的值。

然后也不是特别准确,但是他有这个下面梯度,为什么还大家还用这个梯度公式,是因为它至少在s p h里面,它是对称对称了,就能保证成保证它是动量守恒的啊,然后有了这个公式,大家就可以计算这个gradp。

那么如果你不用这个公式去算这个gradp啊,那你这个系统就会出现各种各样的不稳定性,当然如果说你要算高阶的梯度,比如说lapsing paradi,如果你要算联系的话,那就得算这个拉普拉斯对吧。

那你又有又又有ph,里面又有一套额外的公式来算拉普拉斯,所以这个地方可能是ph里面,不特别优雅的一个地方,那么刚才讲了这么多,其实你要写一个s ph也非常容易对吧,那其实呃刚才讲到上面的这两个公式。

第一个实际是一个应该是欧拉方程,它就是实际上不考虑联性的lai stokes equation,然后呃右边是一个压强,这个是equation of states对吧,它的u s就是说压强关于密度的关系。

那么这个sp啊,这个weekly compressed by sp是它的c是什么样呢,首先第一步注意每个例子,我们去算一下它的它局部的density对吧,注意啊。

这个例子他自己不carry density,这个例子啊,他carry的是它的质量,然后他的dcd是通过质量去估计出来的,然后呢有了这个每个例子上面的desty estimation。

我们可以啊对于每个例子,我们用刚才我们讲的梯度的公式来算一算,这个例子这个地方的压强的梯度,那么有了压强梯度以后,其实就非常好算对吧,因为呃你可以看到这个v对t的导数嗯,我们直接把它带入进来。

你可以得到直接我们后面用一个simply order,就可以和刚才的弹簧质点模型几乎一模一样,几乎一模一样,你可以看到这个s p h和弹簧质点模型呃,其实有很多层面上是非常像的。

你甚至可以认为s p h里面,它其实弹簧是长什么样的,它就是一个粒子和周围的以h为半径的粒子,中间有这么个弹簧,但是这个弹簧它符遵循的不是胡克定律,而是而是s p h推出来的这么一些呃,物理关系。

那么sp是有很多很多的变种,那么这里讲几个我还算有一点了解的,首先呃一个变种是叫做p c r s ph,我们刚才讲的weekly compressed by ph。

它其实是你可以认为它是一个呃显示的格式,那p c r s p h是什么呢,它有点像是一个implicit的一个s p h,它是一个影视的时间积分,但是呢他又为了性能,又他又做了一些取舍。

它不完全是影视的,那他就是呃用的是一个叫预测校正的一个格式,它每次先预测一下粒子的位置或者速度,然后再根据这个预测做出一些校正,然后不断这样校正,不断这样校正,这样就得到一个比较好的一个速度。

这个速度场有什么特点,它的散度比较小,速度场五散,就意味着你这个流体更加接近不可压缩,那么另外一个呃变种最近非常流行,这个几年前提出来的是这个position based dynamics。

这个在实时的情况里面非常频繁的被使用,叫做pdf呃,p bf其实就是pp d position with dynamics,和s p h结合起来以后,得到了一个模拟流体的一个方法。

太极里面其实是有这个例子,这个是荒野大神给我们无私贡献的,我我看一下现在还能不能用,发布了一个新版本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有的时候我都不确定应该是没有什么问题的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

诶看起来没有什么问题,这个就是一个position based fluid的这个demo,大家可以有兴趣的话,可以自己去跑一跑,我觉得还是挺有意思的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后最近还有一个呃叫divergence fs bh的,然后类似的也是一个呃,强行去enforce这个incompressibility一个方法,这个divergence free说的是什么。

divergence free呢,是说的就是他的速度上是divisions frame,如果大家想学更多,有一个three paper呃,这个是比较早的时候。

这个s p h in computer graphics,这个是2014年的时候,我记得我上大二还是大三的时候,我当时就看了这个paper入门,但是最近有一些更新的材料。

大家可以去看我之前提到的这个tutorial,应该是这个六,这个tutorial是一个非常好的ta,它里面有各种各样的demo,如果大家想学的s p a的话,可以去看这个tutorial。

那么说到显示时间积分或者s p h,其实有一个东西啊非常重要,就是说叫做cfl condition,然后一般来说刚才之前我们提到显示时间积分,有一个公式,就是说就是你的呃调查x要小于等于c乘上。

根号下m除以k对吧,那当你的呃系统比较step的时候,你的地铁就不能太大,要不然你的系统就会爆炸,那么这个是从材料的刚度,材料的硬度的角度来考虑的,时间不长的限制,一般来说另外大家还会有另外一个限制。

就是说从粒子运动的速度来考虑,时间不长的限制,那么呃这个叫定义叫cory number,cury number是什么呢,c等于你的粒子运动的最大速度,u乘上da t除以调查x deltx是什么。

deltx在s ph里面,一般就是呃你可以认为它是一个h,顶多差一个常数,就是说一般可以你可以认为是粒子的半径,然后u乘以交叉t是什么意思呢,就是说在一个时间步之内,粒子移动的最大距离。

那么这个数啊你得这个cury number,你在模拟的时候,你得让它小于等于一个c max,这个c max一般来说大家会取几个接近一的值,呃,这个可能是0。1到十之间。

都有可能取决于不同的simulator的数值稳定性,他的这个脾气有脾气好的呃,你可以做到十脾气差了,你可能0。10。1以上就炸了,那么这个c一般大概叫做cfl number。

或者叫quin number,一般或者大家审视的就叫它cl,因为这个corn这个词不是很容易读,嗯然后这个公式有什么用呢,这公式用处大了啊,如果你做任何的影视呃,这个显示时间积分。

你可能都得考虑这么一个公式呃,你考虑要不然你的这个simulation特别容易炸,比如说s p h里面,你这个cfl一般来说,大家就取一个接近0。4的值,如果说你的粒子运动的太快了,那怎么办。

这个时候你就得考虑一下,把调查t是不是该减少一点啊,要不然你的这个呃系统就会非常不稳定,在npm里面呢,大家一般取0。3~1m p m就是material method。

然后flip flip就是fluid,fluid,tracy,particle是一系列方法,如果用flip做smoke的话,一般可以用一个比较大的值,可能是一五甚至12 十都有可能。

当然npm和flip我们后面会详细介绍,如果你要加速s p h啊,那这个里面学问可大了呃,目前为止我们看到这个s p h,它的每一个时间步的时间复杂度是多少,是o n平方对吧,n是粒子数目,为什么呢。

因为你对于每个例子,你都得都得去枚举其他所有的例子,然后去estimate这个例子,局部的呃density也好,压强也好,但是呢在实际情况中,你这个欧文平方这是一个非常非常大的数字。

一般情况下你如果n可能是100万啊,甚至十甚至这个1000万,那n平方那肯定就不能接受了,那实际情况下大家会采用一些空间数据结构,来加速neighborhood search,然后这个就可以呃。

把你的时间复杂度从o n平方到降到o n,所谓这个ighborhood search啊,就是说我对于每一个例子,如果说我能够精确的找到,和它距离不超过h的所有例子。

那么我们是不是就不需要去loop over,其他所有的例子,而只需要去loop over,和我比较近的这些例子就可以了对吧,那么怎么样对于一个例子去找他周围接近,比较和它比较近的例子呢。

啊其实也非常简单,我们可以直接搞一个data structure,然后这个data structure里面就是一个boxl revocal grade,里面每一个boxo去维护一个list。

在这个boxo里面的所有的例子,然后呢,对于呃,我们对于每一个需要去查找它的邻居的例子,我们先locate这个boxo对吧,找到这个boxo以后,我们去看这个voxo周围的boxo。

把这些周围的voxel都枚举一遍,然后对于每个voxo,我们去枚举它包含着这些所有的例子,那么由于每一个boxo里面包含的粒子数目,一般来说是一个常数对吧,有的时候你这个常数一般来说可能是。

比如说几十这么一个,或者几到几十这么一个数量级,所以你每一个例子一般只需要找可能呃几十个,甚至顶多顶多一两百个周围的例子,然后检查一下就可以了。

这个ighborhood search一般来说就是s p h的瓶颈,然后所以大家想了各种各样的fancy的方法,来去加速这个ighborhood search,比如说各种用未压缩呀。

然后用这个morton coding啊,来提高仿存的locality啊,各种各样的单词的方法,大家可以去看看呃,最近的一些paper,比如说competition是一个比较新的s ph的方法。

然后最近同一组的人,他们又在好像是呃eurographic,才是老师发了一个更新的各种build,这个ighborhood list的方法啊,这个里面加速的学问可大了,这边我就不继续说了。

我看看有同学们有没有什么问题,有同学问vocal数目也很大,对数目确实很大,但是呃对于每一个particle,我们不需要去loop over所有的box,我们只需要loop over它周围的3x3。

这个是二维,如果是三,我就3x3x3,就是927个boxo对吧,那么927个boxo,相比于你可能有总体有100万个box来比,这还是一个很小很小的自己,ok然后刚才讲了s p h。

其实基于粒子模拟方法还有很多很多啊,比如说这个呃叫dm,这个叫离散元素模拟方法,这个在graphics里面也很常用,就是所谓dm就是相当于你考虑每一个例子,就是一个钢铁小球,然后有一些复杂的物理。

你可以用它来模拟沙子啊,模拟一些其他的其他的这个物质,另外呢还有mp moving particle,siming place it,它其实是一个和ph有点相近的方法。

但是它会在局部建一个personequation,我去把这个呃presuequation can solve一遍,这样使得你的流体不可压缩性更好,还有power particles。

这个是相当于用power diagram和一些particle来做的,这个incompressible fluis sober,然后这个是一个所谓power diagram。

其实就是一个呃v diagram,不是lai diagram的一个呃generalization,然后他们用这个build这个particle,周围的veronic diagram,能它主要的一个好处。

视觉上主要一个好处,就是particle之间的间距会非常非常的均匀,另外呢还有paradiamics,这个如果大家感兴趣,他在图形学里面应用的话,你可以看一看下面的这篇文章,还是挺有意思的。

ok啊我们讲完了ph,那么我们接下来讲一讲一个实用技巧,就是说怎么把你的结果给它输出成一个mp 4,然后怎么把mp 4转化成呃gift,这样然后你就可以在论坛上面share一个gift。

那这样就比你share一个静态的图炫酷多了对吧,那么呃其实主要还是大家可以看文档,这边只是大概介绍一下,如果说你要呃从你的这些真里面做一个mp 4 video,你首先得把这些真写到磁盘上面。

那么有两种方法,你如果用ti点故意的话,你可以用ti点勾一点show,就可以把这些再带一个文件名,就可以把这些呃真全部存到你的磁盘上,或者呢如果你是一个现成的一张图,如果是一个image。

是一个npo ri,你可以直接用image im right给他写到磁盘上,那么当你的磁盘上面有了这些针以后,你可以用呃一个命令叫ti video,然后他就可以把你的所有的帧变成一个,v6 点mp 4。

这个时候呢你还可以去指定一下你的帧率,可以是24帧啊,或者60帧啊都可以,然后呢你可以把它convert成一个呃,你有了npc以后,你可以把它converter成gift,这个论坛上面我看到有同学呃。

也有同学提供了怎么用f f m g的方法,但是那个方法,可能学起来有点难,但是可定制性更强一点啊,太极提供的这些简单的这些函数,其实就是基于f f m pad给呃简单封装的,然后它的功能比较比较比较少。

但是大部分情况下也够用,那么你如果要进行这个操作,ti video ti gift的话,得确定你有f f m act,那如果你是用linux或者mac的话,基本上很大概率你的机器自己就带有这个软件。

你如果用windows的话呢,就得手动装一下,那这个大家可以看一下文档,ok那么这一部分我们就讲到这。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果大家对sp感兴趣,可以去check一下,我们有一个助教同学写了一个c加加的,基于c加加和kda的一个s p h的sa,我本来想写一个太极,基于太极的,但是后来一直没有时间,所以但是还没有写后面。

不过我相信论坛上面肯定会有同学,很快就写出来一个,然后大家可以看一看它的实现就可以,当然实现一个s h呃,最基本基础的版本也不会特别难,这个c加个扩大版本在giharmony上面有代码。

上面实现了wc s p h,然后p p f还有刚才提到的df s p h,这边展示几个demo。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么接下来我们一起看一下最近的一篇。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

s p h的一篇很好的paper的一个video,这篇paper啊是是一个top还是swap paper,然后它是用来做s p h和单体的耦合的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所谓耦合就是说呃,你的钢铁和你的s ph模拟的流体能够双向交互,他这个所谓的这个啊,但是这个耦合有单向耦合和双向耦合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我刚才说的是,如果双向交互的话,那这个是一个双向的耦合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这篇文章做的叫做所谓的强耦合,强耦合呢一般来说就是指呃,我在解线解这个线性系统的时候,或者我在迭代的时候,把两个系统同时进行联立的求解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果是弱耦,可能弱耦合就更简单一点,弱耦合可能就是呃我先解流体,然后把流体作为刚体的边界条件,解刚体,然后再把解出来的钢铁作为边界条件去解,流体量的话,这个耦合就会相对来说更弱一些。

这篇paper提出来是一个强吻的方法,嗯我这个视频好像又不太放不了了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok,那我就放几个例子吧,后面我会呃真的作者同意,然后把这个视频看看能不能传到b站,这样大家看起来就方便一些,好像确实一放这个视频就有点卡。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这边主要呃我其实最喜欢的demo是这个,我觉得无论如何就算卡了也要放一下,这个还是一个挺有意思的一个demo,还有是不是在不全屏播放。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

会不会好一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

哎呀不全屏播放就没有进度条。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到他其实s p h啊,现在已经早就不是只做流体了,现在s ph也可以做各种各样的东西,今年s8 还有一篇sp h模拟雪的方法,然后这个其实它是用sp是在模拟很多钢铁。

s p g和m p i非常像呃,它有一个很大的好处,就是说它可以比较好的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比较容易的模拟各种介质的耦合,比如说流体啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后弹性物体啊,然后钢铁啊都可以,嗯算了,我就不手动播放啊,现在好像好一点,当然这些每一帧都是要算很长时间,它不是远远没有达到实时的标准,这个地方sp它有的时候它的视觉上面看起来。

它会给人看起来非常splash,他会你会觉得他的例子好像在空中,像有点爆炸的那种感觉,我个人不是很喜欢,当然有一些场景你可能会确实需要这样的效果,这个special的这个问题,你可以看到它这边的例子。

它会生成很多很多的splash,然后这个splash中间往往是空的,看起来有的时候就不会特别好,当然你如果加了表面张力,这个问题可能会减轻一点,ok那么我们今天就先讲到这儿。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我来回答一些问题了,我看看模拟输出个例子以后,怎么生成真实的水面啊,这是一个很好的问题,surface reconstruction,也就是说这个表面重建,从粒子生成表面的mesh呃。

这个是一个很大的话题,一般来说这个有很多很多很多很多搞法,最典型的最基本的一个方法叫做marching cubes,marching cube,就是说呃我把整个空间用很多网格,把它打一个背景的网格。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我可以搜一个图,反正,然后我们用一些三角形去填充这个网格,你可以看到他他其实做了什么事呢,所谓这个martian cubes,就是说我对于这个格子上面的每一个点,我去算一下粒子的密度。

然后我尝试去画出它的iso counter,就是说只等于零的等式面,一个等势面,然后这个等式面呢,其实就是用各种三角网格去近似的,这个market cube是一个非常非常经典的方法。

它实现起来会稍微有点麻烦,因为他情况非常多,你可能比如说这个看这有14种情况,实践起来就非常的麻烦,我相信你如果把呃,很多不同的复杂的情况考虑上去,远远不止14种,实现起来还是挺挺烦的。

但是他毕竟还是一个,可能你不管怎么弄,最后都得上marching cubes,然后你在做market之前,还有各种各样的预处理,smoothing啊之类的操作,这个你可以去看b d b。

bgp里面有各种各样的呃operator,可以看看能不能搜一搜,看看能不能找到,对现在呃工业界里面一般来说比较常用的搞法,就是就是用b db,先把particle给它光栅画到一个背景网格上面。

然后在背景网格上面做一些适当的嗯level set,所以level set就是你particle会嗯光栅化的粒子网格,光光栅画楼背景网格上面你会有一个呃距离场,然后在这个距离场上面可以做各种各样的操作。

比如说你可以让他呃变得更圆滑,或者让它变得更加的尖锐,这些都可以,然后你在做完v db的各种操作以后,你就得到一个density field,就是dd field,然后你就可以上门tgps。

嗯这个大家可以去看一看v d b,反正v db还是一个非常成功的一个系统,很多电影都有,然后v d b是拿了奥斯卡奖的,那个作者是当时拿了一个camera,拿了一个,因为bdb拿了一个奥斯卡学院奖。

好像呃对还是很厉害的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我再看一看别的问题,屏幕空间方法效果和v m c d b打印哦,对这是一个好东西,我刚才忘了,其实有很多时候大家会渲染的时候,会直接往free buff上面去渲染流体。

这种方法在实时应用里面其实还是挺常见的,但是在电影里面就很少用,因为电影里面你的camera会不断的移动对吧,那样的话很少用,但是我觉得他还是有很大优势,因为他手速度很快嘛,所谓屏幕空间方法。

也就是说我直接把这个例子打到投影到屏幕上,然后在屏幕上面去做一些像光线的折射啊,反射啊之类的操作,那么这个其实就是实时渲染的一套理论了,实时渲染里面有各种各样的近似,使得它能够在有限的计算资源里面。

能够达到一个大家可以接受的帧率,呃有同学说预习材料其实大纲在对,就是课程大纲其实是在知乎上面啊,包括课程论坛上面或者github上面都是有的,但是我感觉以后可能会对内容做一些删减。

因为确实我发现嗯每周一个小时的话,或者一个半小时能讲的东西其实挺有限的,像今天我们就只讲弹簧质点系统和s p h,我觉得能把这两个基本的东西把它讲好,其实已经啊大家能够掌握好,其实也已经挺不容易了。

所以后面很多东西我可能会删掉一些,大家可以挑,如果想预习的话,可以挑后面的一些比较简单的内容去提前看,ok那么要不我们今天就到这边吧,如果大家还有别的问题呢,可以直接在论坛上面打印出来。

好那么今天就这样,如果大家想继续写homework里的话呢,还可以继续写,然后我们还会继续挑出一些比较好的作品,然后呃刚才我演示的两个demo,一个是vespring system。

一个是jope inter,这两个demo的代码都上传到论坛上面了,然后大家可以尝试一下,把这个两个demo整合起来,去写一个呃in格式的best princess,这个还是挺有意思。

当然要把它写对很不容易,特别是你要求各种各样的导数啊,那个求导数还是一个挺头疼的事情呃,ok那么我们就先这样,那么我们下次再见。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下周再见,下周我们会出一个新的作业,然后呃会进入新的一轮的评比,然后希望大家能够做出更多更惊艳的作品,ok好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GAMES201:高级物理引擎实战指南2020 - P3:Lecture 3 拉格朗日视角(2) - GAMES-Webinar - BV1ZK411H7Hc

OK那欢迎大家再次回到我们的课程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们已经进入到第三讲了,这一讲呢我们主要讲讲弹性,讲讲有限源的基础,然后讲一讲一些高级的太极特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先还是一些课程的一些后停工作,这个作业安排,作业零呢我们已经告一段落了,大家如果想提交的话呢还可以继续提交,但是不会再有奖品了,今天呢我们还会再继续评出几个比较好的作品,关于作业零。

作业一今天发布过会我们会提到,时间呢大概是6月15日到7月11日,其实是一个跨度非常长的一个区间,然后我们预计中间可能会空一周,这样留一点时间给大家去实现自己的作业。

然后也留点时间呢给大家去消化我们讲的东西,因为大家普遍反映我们讲的东西呢,可能其实信息量还是比较大的,然后我们一到三日组队,每一组可以独立完成,尽量独立完成,然后可以在论坛讨论。

但是大家最好不要复制粘贴别人的代码,这个就不是特别好,然后作业二呢就作为我们最终作业,大家可以实现一个可以交互的物理模拟器,QD的也可以实现一个高质量的渲染出来的,可视化的物理结果,可以是3D的。

你可以用第三方渲染器,也可以自己写一些渲染器,用太极写,然后呢也可以进行一些代码优化,你可以基于自己或者别人的homework1来做homework2。

那么其实就是说homework内部大家是不要复制粘贴,但是homework2可以复制粘贴别人的homework1,这样呢这样就促进大家代码交流,然后也保持一定的独立开发。

homework3呢我们暂定就取消了,因为现在的情况看来有的homework012其实工作量已经很大了,OK那么这就是作业的情况。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二轮作业获奖选手我们又评出了五个奖品,分别是2D光线追踪,by这个quadpixels,然后呢还有一个vertex method,fluid simulation,以及分子物理学模拟。

实时光线追踪渲染器,还有一个类鸟生物群体模拟,我这个南方人鼻音边音不太分得清楚,说到这个类鸟生物群体模拟应该读对了,这是五个获奖选手,然后还有两个honorable mentions。

分别是wcsph和implicit mass spring,那么之所以这两个选手其实做的也非常好,但是为什么放到honorable mentions呢,主要是因为他们已经提前做了作业1的内容。

并且workclass同学已经是获奖选手了,所以我们就不再额外的颁一个奖了,那么这两位同学可以把自己的作业再完善完善,直接进入作业1,OK那么作业1是个什么状况呢。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作业1我们的题目叫做,显示时间积分器与影视时间积分器的对比,那么大家知道在物理模拟中,可能如果有同学尝试实现显示和影视时间积分器,就会发现显示时间积分器非常容易实现,但是它数值上比较容易不稳定。

对于时间不长的这个DT大小非常敏感,如果你DT稍微大一点呢,可能你的性能就炸了对吧,但是影视时间积分器呢,它稳定一些但是它较难实现,比如说你要去求先行系统,你可能要多次迭代,你可能得求各种各样的导数。

那这个求导数是一个非常头疼的事情,那么可能大家如果去写过implicit solver的话,那很可能就知道这个其中的头疼之处,在DT作业中啊,大家可以选择自己喜欢的模拟器。

同时实现显示时间积分与影视时间积分,然后呢从性能准确度数值稳定性,各种角度进行对比,可选的模拟器呢有影视的弹簧试点系统,你可以实现这个影视的FBM,然后一些不完全影视的一些。

介于影视和显示之间的一些格式,比如说PCI-SPH,然后比如说这个完全影视的DFSPH,或者NPS这个Moving Particle Simulation,那么建议大家分工合作,所以建议组队。

你如果愿意一个人做呢也完全没有关系,但组队了以后有什么好处呢,组队以后呢大家就可以互相,一眼算影视时间积分器的公式,因为大家可能推过公式就会知道,一个人把这个公式推对还是有点难度的,提交格式呢。

建议大家在Github上面拖款自己的代码,然后在论坛上面放一个Github的链接,因为这个代码量可能稍微有点大了,如果你在论坛上面贴出来,你可能就有个两三百行代码,别人看起来也不是很方便。

所以Github上面呢,其实分享你代码就比较容易一些,然后论坛上面可以放出一些关键图表就行,比如说你可以放个两三个图,可以是数值准确度关于dt的关系,可以是数值准确度关于你的材料硬度的关系。

加入一些比较简单的分析,促进大家分享就可以了,其实大家不用写特别多的文字,这个实验呢主要是放一些图表,放一些可视化结果就其实很不错了,不用花特别多的时间去写很多实验setup,这些很细节的东西。

我个人是比较不喜欢写这些东西的,如果大家不愿意写的可以不用写,如果愿意写的也可以写多一点,那其实没有关系,那么和作业零一样,我们还是会评出一些优秀的作品,但是这个作业时间可能会花的时间比较长一些。

所以我们可能过两个星期以后,我们再进行评奖工作,OK。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么由于有一些同学表示第二奖稍微有点难,然后我们驻家团队就进行了一个难度的问卷调查,其实问卷调查出来,我们发现其实41%同学认为我们难度是适中的,41%同学认为比较难,然后12%同学认为太难。

也有3%4%同学认为比较简单,那么我们因为这个课本来就是一个体育课程,所以我们其实我一直是觉得你人活着,总是要做一些自己没有做过的事情,对吧,你得做一些有难度的事情。

如果一直每天做自己觉得很简单的事情的话,那其实就生活也很无聊,对吧,所以我们还是觉得我们觉得这个难度的分布其实还可以,那么就41%较难,41%适中,我觉得其实属于一个合理的难度范围。

因为我们这个课本来就提高课程,所以后续我们就会保持这个难度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么今天我们就讲一讲弹性,弹性里面主要有几个话题,形变与形变梯路,deformation and deformation gradients,然后strain and stress,硬力和硬变。

然后hyperelastic material,这个是超弹性模型,这些都是图形学里面常用的一些术语,大家现在完全听不明白没有关系,我们后面会详细讲,我们还会讲一讲最最最基本的线性有限元。

然后它是在线性的tetrahedral,或者triangular meshes上面,然后我们还会讲讲一些比较高级的态极的feature,因为毕竟大家后面都要写一些复杂的态极程序了。

有些态极的feature可以让你提高代码的可重用性,OK那么我们话不多说就直接开始吧,OK还是一部分用keynote做一部分用latex做,这样比较打工时就稍微审视一下。

OK那么第一部分我们来讲一些比较基础的形变弹性和有限元,这部分其实是一个非常有意思的内容,因为模拟弹性物体其实是一个非常有趣的事情,因为首先它会带来不错的视觉效果。

你可以看到这个东西很Q弹就觉得很有意思,那么它也不会特别难以实现,你如果用态极的话可能100多号代码,就可以实现一个简单的一个2D的FEM的弹性simulator,然后弹性也是其他的材料的基础。

比如说弹粘性弹束性,包括各种各样其他的更fancy的材料,其实它都是基于弹性的材料进行一些比较细微的修改,你就可以进行这些更复杂材料的模拟,那么今天我们讲的内容其实是比较基础的内容。

如果大家课后还有兴趣的话,可以看一看这两个教程都是图形学的领域里面,大家比较喜欢的关于弹性关于有限元的一些教程,这两个教程其实都是属于写得非常通俗易懂,OK,那首先我们讲一讲形变,什么是形变呢。

形变其实如果你要描述它,那其实就是说一个材料,如果它的现在的材料的位置和它静止状态的位置,发生了变化,那么我们就可以认为它发生了形变,那么我们怎么来描述这个形变呢。

一般来说最常用的这个描述叫做deformation map,也就是说这是一个函数,它能够把我的静止位置映射到我的形变位置,OK,那么这是一个其实如果你在三维里面的话。

这个函数就是一个从三维下量到三维下量的一个下量函数,那么你如果把deformation map去对于你的静止位置,去求一个导数的话,你就可以得到deformation gradient。

也就是说你的形变的梯度,如果你观察这个deformation map,它这样一个性质,你可以发现如果说我有两个deformation map,分别是phi1和phi2。

如果phi1和phi2只是在于最终位置差了一个常数的话,那么它其实它的形变梯度其实是一样的对吧,因为你这个c求到以后,它就其实消失了对吧在导数里面,然后另外一个很常用的一个符号叫做j。

这个j是你的形变以后的体积,除以你静止状态的体积,那它其实就是你f的行列式,或者它这个叫做,其实叫做Jacobian determinant,你的形变位置对于静止位置的Jacobian。

其实就是f它的行列式,就是它的这个体积的变化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这边我可以做一个简单的demo,我们来找一个容易形变的物体,比如说这个海绵宝宝,你可以看到我这边给它做了一个切向的形变,然后左边是它的静止的位置,右边是形变以后的位置,然后你可以看到。

其实这是一个非常清晰的映射对吧,如果这个是静止位置,比如说我考虑这个海绵宝宝的头上的右上角,这一个点就是xrest它的静止位置,那么对应的它的形变位置是哪呢,就是这个地方对吧。

如果说比如说是左上角这个点,对应的就是左上角的形变以后的这个点,两个靴子它其实也是一一对应的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到这个地方它的deformation gradient,这个程序里面,我课后会share这个程序,我还一直没来得及上传我的这个程序,你可以看到它是一个,它决定长什么样,它是10 0。51。

它其实是一个,一个这样一个sharing的一个矩阵,我可以其实把它改一下,我把它改成1002。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么其实这个deformation是什么样的,这个deformation会在纵向去拉伸这个海绵宝宝。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对吧,我可以再把它改一改,我把它改成,如果是20 0。1。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么我就横向拉伸了这个海绵宝宝,OK那其实这个是一个,形变梯度的这么个概念,就是说如果形变梯度呢,它你把第一行全部乘上,你如果把这个形变梯度第一行全部乘上一个场数。

那它这个你的海绵宝宝就会在横向去做一个拉伸,按照这个场数拉伸,类似的你可以去操作它的第二行,好那么我们继续。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

哦对我一直忘了demo,我其实还有一个demo,我刚才提到用太极实现这个弹性模拟,其实非常容易,这里是另外一个demo,这个是一个弹性长条,它是用有限元来实现,比较简单的有限元,后面这节课后半部分。

我会讲到这个demo,这个应该是一个Neo Hooking的材料模型,这个是一个显示的时间机,你可以看到它不是特别稳定,如果我现在移动这个球,这个球是一个creation object。

我移动的时候非常小心的,因为这个边界条件没有,为了代码简单没有把它做得非常的细致,如果说我大力移动它,这个就会出现一些问题,我其实可以演示一下,我大力推一下它,它就会变得非常的不稳定,如果我说我把它。

我让它这样滑下来,你可以看到它就会,这个有限元里面,处理自己和自己碰撞,是一个非常头疼的问题,它就会自己和自己去overlap,在这个二维的空间里面,其实不是特别的物理真实,这个有限元里面。

自碰撞也只是一个比较头疼的事情,尤其是有它有这个问题,很多人还是很喜欢用有限元,因为它还是有很多自己的优点,后面我们会提到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个代码其实非常短,其实可能也就133号,你看它其实没几个kernel。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可能就两三个kernel,这个代码我后面会share给大家,对我其实说一句,如果大家喜欢写python的话,一定要用vim,我用vim是因为我开ide的话就太卡了,这个电脑实在是有点吃不消。

所以我一般平时写代码虽然我用ide,但是我在上课的时候我用vim,这个原因就是vim占用资源小一点,那么下面我们来讲讲弹性,什么是弹性呢,弹性其实就是有一些,你有个橡皮筋你去拉一拉它,它会回到静止状态。

你去松开它会回到静止状态,那么弹性其实就是一个材料,它有回复自己静止状态的一个性质,那么这讲我们就讲一个比较简单的弹性模型,叫做超弹性模型,hyperelasticity,那么超弹性的材料它有一个性质。

它的stress-strain relationship,是被一个strain energy density function来定义的,这里面有很多很多术语,但是我后面会一一解释。

那么intuitive的理解,就是说我的这个psi它是一个potential energy,那它这个potential energy会惩罚你的形变,对吧,它会惩罚你的形变。

那这个potential energy在hyperelasticity的材料里面,它就是实际上是一个f的函数,注意它这个是一个密度,它不是一个总的能量,它是单位体积的势能的密度,那么什么是stress。

什么是strain呢,stress就是中文好像叫应力,因为我是我本科没有专业学过这些东西,所以我其实我在学它的时候,我已经在一个英文的环境里面,所以我其实有的中文,不是特别清楚它的对应关系。

我只能尽量的去说如果说错了,请大家原谅,这个stress应该是叫中文叫应力,就是说材料内部的这个,它有一个内部的弹性力,这个stress在hyperelasticity里面,其实它就是用来恢复这个材料。

用来恢复自己原来体积形状这么一个内力,那么strain就是,strain就是说这个叫中文好像叫应变,就是说它这个你的材料的形变的一个measure,stress和strain都有很多很多种表述。

然后stress有各种各样的stress tensor,然后strain也有各种各样的表述,那么我们这个课里面,大家其实看到strain。

其实把它用deformation gradient f去替换掉就可以了,你可以认为strain它就是deformation gradient,当然还有各种什么green strain。

乱七八糟的很多很多的术语,我这边就不细一细讲了,因为我怕说反而会影响这个教学制度,因为这个概念太多了,那么这边要注意一下,我们有两个非常相近的符号,一个叫psi一个叫phi对吧。

然后psi我们是用来表示strain energy density function,然后phi我们用来表示deformation map,它们长得很像,但是它们其实完全不相关了其实。

什么是stress tensor,我刚才讲到stress是,你如果考虑一个材料的微元,那么这个stress其实你大概直观上理解,就是这个材料微元它会和其他的材料微元。

进行一些相互的推拉之类的相互作用对吧,那么stress tensor其实就是一个33的矩阵,或者说你可以认为它是一个二阶张量,它有什么作用呢,它可以你如果给它一个很小很小的一个小的截面。

然后你把它这个反向量乘上stress tensor,你就可以得到这个材料,它向周围的neighborhood去施加的力,那么这个可能比较抽象,我们具体的讲几个三种常用的stress tensor。

在图一元里面如果根据大家不同的需要,我们可能经常会用不同各种各样的这个stress tensor,比如说比较常用的一个stress tensor叫做。

D-Parallel Kirchhoff Stress,这个一般或者大家简称叫做PK1 Stress,那么PK1有什么好处呢,它有一个很好的好处就是。

P就是PK1 Stress如果在F点的求值等于什么呢,等于你的Pcf关于F的求值,也就是说你的String Energy Density Function。

关于deformation gradient求的导数就是你的PK1 Stress,OK,这个其实,其实你是在这个rest space里面去进行的这样一个计算,这个非常非常容易计算,但是它有一个问题。

就是说它是在rest space里面的一个tensor,你如果实际上要来算材料的受力的话,你得在它的形变以后的这个空间里面去计算,那么我们就得做一些变化了,那么常用的在形变的空间里面。

大家一般会常用Kirchhoff Stress或者Cauchy Stress,其实更常用的是这个Cauchy Stress,它是Cauchy Stress是一般也叫做True Stress。

它是一个真正的在形变空间以后,里面的硬力的一个张量,然后这个tensor有一个性质,它是对称的,因为角度量守恒对吧,你这个有一个推导过程,这边我就由于时间关系,我就不过于详细地讲了。

那么它们这三个tensor之间是可以转换的,比如说你的这个tau等于j乘上sigma,或者等于你的p乘上f的转质,然后p呢等于jsigma f负转质,这个所谓负转质就是先取转质再取力。

或者先取力再取转质,这两个是一样的,那么这个traction,traction就是我刚才提到的,如果说你把你的stress tensor乘上你的在材料内部的一个小的截面的发酵量。

这边你其实就可以得到材料内部的一个截面的这个traction对吧,它就是这个中文叫什么我也不太清楚,我课后我去查一查,然后再补充给大家,或者大家自己去百度上面或者google上面查一查,那么。

这个p和sigma之间这个关系其实看起来有点复杂,因为p等于jsigma f负t对吧,那么这个地方其实它是有一个intuition,为什么是f负t呢,这个就很奇怪对吧,为什么不是f的力或者一个f转质。

因为我们这边要变换的是normal,是你的这个材料,是你考虑这个材料的截面的发酵量,这个发酵量它其实转质的公式其实是f负t,这个其实就大家可以下课以后去推一推。

然后几个常用的描述elasticity的描述材料的弹性的属性,首先阳术波量对吧,阳术波量这个大家应该都比较熟悉,大学物理里面都会讲到,或者可能高中物理里面也会提到。

其实它最简单的理解就是你可以认为你有一个弹簧,其实就是弹簧里面的一个k,对于三维材料是稍微稍微复杂一些,因为你去拉这个材料的时候,比如说你有个橡皮筋,你过去拉它的话,你拉这个橡皮筋的时候。

你会发现它中间的那一部分其实是会变窄的,因为你这个橡皮筋它有一个正的possense ratio,它的这个波松比是正的,然后这边就提到波松比是什么呢,波松比其实就是定性的来说,这个波松比如果是0的话。

你去拉这个材料,假设你手里面现在放了一根橡皮筋,如果这个橡皮筋它的波松比是0的话,你拉它的时候,它中间的这个截面面积是不会缩小的,也就是说你拉它的时候,它体积就很大程度上你拉多长,它体积就变大了多少。

然后如果说你的波松比比较大,那它其实更接近于不可压缩,也就是说它尽可能的接近保持自己的体积,那什么意思,你如果把这个橡皮筋你左手右手一拉,它其实变长了对吧,那它要保持自己的体积,那它会怎么办。

它会把中间其实就变细了一些,这个其实更符合大家的直觉,因为你橡皮筋拉了以后,它肯定中间是越来越细的,它到了一定程度以后,这个橡皮筋就怎么它就断了对吧,那么有没有材料的波松比是负的呢。

也有这个材料一般叫做Oxidix,它可以有一个负的波松比,什么样的材料会这么奇葩呢,因为我以前搞过一段时间3D打印,这个3D打印里面你可以打印出来一些,有负的波松比的这些材料,负的波松比什么概念。

你如果去这个橡皮筋你拉它以后,它中间反而会变粗,这个听起来就非常的神奇对吧,那么介绍这个波松比这个概念以后,其实大家就会想到,既然这个材料你如果去拉它以后,它的体积会发生变化。

那么如果说我要考虑它的压强,关于它的体积的这个体积变化的,这么一个modulus,这个一般是在液体里面可能用的比较多,这个Bulk Modules可压缩液体里面。

那么大家就会用到这个Bulk Modules,OK,然后还有Lame’s Parameters,一般大家会用这个λ和μ,λ有的时候也叫做Shared Modules,一般有的时候也会写成G。

但是图形学里面一般会就写成λ和μ,这些材料参数其实都可以相互转换,它们都是正比于Young’s Modules E,所以一般指定了Young’s Modules和波松比以后,其他的全部都是可以算出来。

大家一般也就只指定Young’s Modules和波松比,然后如果在固体里面,一般大家就用λ和μ,然后但是λ和μ不是很直观,对吧,因为大家刻画材料一般习惯于用Young’s Modules和波松比。

所以大家一般会指定λ和μ,然后去,Sorry,大家一般会指定E和ν,然后通过E和ν来算出λ和μ,然后K一般是在模拟可压缩液体的时候会用,这个其实用的不是特别多,常见的超弹性模型有哪些,在图形学里面。

大家常用的是Neo-Hooking和Curl Rotated,Neo-Hooking其实是更为,可能在力学社区里面也更加常用,基本上在图形学里面Neo-Hooking基本上所有的弹性介质。

如果是isotropic的话,就是你如果是各项同性的话,很多时候大家默认就采用Neo-Hooking,除非你的形变非常小,你如果形变很小的话,你可能会用线性弹性Linear Elasticity。

Linear Elasticity有什么问题,如果Linear Elasticity的材料,它有一个问题就是说,你如果去旋转了它以后,它并没有保持自己,怎么说呢。

你旋转Linear Elasticity的材料以后,它可能体积就会无条件的变大,然后不受到任何的惩罚,这个就非常奇怪,你如果有一个材料你去转一转它,它还是能保持自己的势能为0,但是它体积会变大。

这个不是特别物理,那为什么Linear Elasticity还是很有用呢,如果说你是做一个小形变的分析的话,你就不会有红关上的deformation,然后你也不会去旋转它。

所以这个时候Linear Elasticity就非常有用,而且它导出的方程一般是一个线性方程组,就非常容易去解它,为了fix这个Linear Elasticity旋转以后,体积无条件变大的问题。

大家就提出了quotation,quotation一开始提出的版本稍微有一点小问题,所以大家后来又搞出来这个叫fixed quotations。

现在如果说quotation一般就是指fixed quotations,然后你可以看到它的perceive是一个关于f的函数,然后这边我就直接给出公式了,它中间其实有一些推导过程。

比如说你可能会要去求f的一个thinker value,就是它的特征值,f的特征值一般是什么含义呢,就是说你这个f有旋转的部分,你把旋转的部分给它t了,t了以后就只剩下拉伸的部分。

一般这个sigma你可以认为是它的,这个sigma不是stress,这个sigma就是singular values,然后这个perceive关于f的公式给出来以后,你就可以求出它的pk1。

它的pk1一般就是,它的定义就是perceive关于f的导数,这个求导这个过程还是挺有意思的,大家可以去自己推一推,或者看一看教程,看看教程里面是怎么去推的导数,这个导数还是一开始的话。

说实话不是特别容易把它搞对,不过这个还是一阶导数,这个perceive关于f求出来是一个2x2的,一个张量或者是一个2x2的矩阵,如果说你要求它的二阶导数的话。

你如果写implicit solver的话,你得求二阶导数,二阶导数这个就算爽了,这个算出来就是一个,三维里面就是一个3x3x3x3,这么一个应该是81个元素的一个四阶张量,那样就体验不是特别好。

推导过程体验不是特别好,所以我自己其实也不是很喜欢implicit solver,因为太复杂了,OK那么讲了弹性以后,接下来我们简单介绍一下有限元,那么有限元它其实是一套非常博大精深的例子。

它是一个generating方法,那其实它做什么事情呢,它就说你的PDE不是连续的吗,但我在计算机里面只能表示离散的,我只能有离散格值,那怎么办,我得做一个离散化的工作对吧。

那么我怎么把这个连续的PDE给它换成一个,离散的方程组呢,那么我们肯定不能用PDE那种主点方程的方式,或者说它的强行是strong form来描述我的物理系统,那怎么办。

我去搞一些小的test function,它其实去把这个强行是在局部做一个积分,然后我现在不要求它的主点这个方程满足,而是这个方程的residual关于你的test function,积分以后得到满足。

而这个后面细节我们会在课程的后面我们提到,这边呢大家只要知道,FEM其实最基本的概念,其实就是说我们把这个空间,二维空间也好,三维空间也好,把它分成很小很小的element,这个element是什么。

可以是二维里面的可以是这个三角形,可以是正方形,或者叫这个四边形,三维里面的可能是四面体或者六面体,然后还有很多很多更加fancy的element,网上有一个叫有限元素周期表,我其实可以打开看一下。

这个还是挺有意思的,叫FEM table,这个其实有点丧心病狂,我到现在也没有完全搞懂这个东西,但是大家如果有兴趣的话可以去看一看,这个是用这个叫有限FEEC有限元素外微分。

其实是用离散微分几何的方式来去讲,就各种有限元素,那我们一般用的,最常见的其实就是最简单的这些,比如说图形学里面这个可能就用这个三角形元素,然后四边形元素,然后你的未知数存在哪,存在这个元素的顶点上面。

这个大家可以暂时这么信,那你可以其实看到更加复杂的元素,它并不一定是,它的degrees of freedom,它自由度不见得就是存在它顶点上,可能存在边上,可能存在它这个体里面。

这个网站上有一个简单的background介绍,但是说实话可夺性不是很强,这个大家如果不想自虐的话,你可以暂时不去看这个东西,但是还是有这么个东西还是挺有意思的,对吧,有限元素周期表。

和化学里面的一个元素周期表,有一举同工之妙,OK我就不继续扯淡了,就是说最基本的概念就是说在FEM里面,大家只要记住它是一个Gallery方法,然后它用Weak Formulation。

这些概念我们后面会在深入讲FEM的时候,我们会继续介绍,然后这边大家只要知道,我们把空间分成了很多很多个三角元素,我们今天就讲三角元素,当然刚才大家也看到有很多很多其他的元素,对吧。

那么FEM里面我们今天讲一个最最最基本的,叫做Linear Tetrahedral Triangular FEM,什么意思呢,它是我们如果解这个弹性问题的时候,大家经常会用到这个线性的三角网格。

或者四面体网格,它做一个最最最简单的assumption,是什么呢,就是说你的deformation map,你的这个File,它在每一个元素里面是一个FM变换。

或者说它的deformation gradient,在这个里面是一个constant,什么是FM变换呢,AX加B就是FM变换对吧,那么我们其实有这么个公式,在一个元素里面,注意这个只是一个元素。

这不是说你的整个simulation domain,如果你整个simulation domain都是这么个变换的话,那你这个F就是整个domain都share一个F,但是那样的话。

你基本上就不是在模拟弹性物体对吧,你这个物体的这个限制就太大了,一般弹性物体就是每一个元素可以自由的变换,可以自由的发生形变,那么在一个元素之内呢,我们有这么个关系,它的形变以后的位置。

等于静止的位置乘上F再加上一个B,B是一个offset对吧,那么我刚才提到,这个B其实是不会被你的势能去平等化,因为你如果平移一个有限元的话,你平移一个物体,它并不会受到,它并不会产生形变对吧。

它会产生形变,但这个形变并不会被你的,并不会产生弹性势能,那么对于三角形线性的这个element,这个是在图形学里面非常非常常用的一个格式,对于每一个元素,我们可以计算它的弹性势能对吧。

这个弹性势能是什么呢,这个是注意我这边少写了一个DX,其实就是说它的string energy density function,它是一个这样能量密度函数,关于体积的积分积出来就是你的弹性势能。

那么我们刚才有这个assumption,就是这个F在这个element上面是一个常数,那么我们就可以把这个积分直接换成一个,density乘上体积对吧,因为你的这个psi也是一个常数了。

psi是F的函数,F是常数,那么psi就是一个横常量在这个元素里面,那么我们可以直接用ve就是这个元素的体积,二维里面就是面积了,乘上density function,ok这就能计算这个元素的弹性势能。

这个弹性势能算出来,那就很多事情就很好解决了,对吧,为什么呢,因为你的力这个力其实就是势能关于位置求导数以后,再取一个负对吧,就是势能的定义,那么怎么去compute。

我们怎么去计算这个元素它的deformation gradient呢,其实对于三角元素的话,这个也非常非常容易计算,那么我们来这边就现场推导一下,那么我们要记住deform的位置呢。

等于f乘上静止位置加上一个b,对于三角元素我们假设,我们就在二维情况来思考这个问题吧,就是二维里面三角形其实是什么,是有三个零点对吧,ABC,那二维里面三角形推广到三维以后呢,就是实际上是四面体。

它就四个零点,ABCD,但我们这边出于简单性,我们就考虑二维情况,ABC它的静止位置,它形变以后位置呢,是A deform B deform C deform,它有三个形变的位置,OK。

然后呢在一个线性的三角元素里面,f是一个它的deformation gradient,是一个常数对吧,那么我们有A deform它等于什么,等于f乘上A rest加b,那么类似的我们对于b和c。

也有这样一个性质,注意我这个右端向的这个b和b deform,和b rest不是一个b,这边我其实写的不是很清楚,我后面我讲的时候才发现,我们后面应该,后面的课件我会把它稍微更新一下。

那我们要首先做一个事情是什么呢,因为我们并不关心这个offset对吧,我们并不关心这个constant offset,我们先把这个b给它消了,怎么消呢,很简单对吧,我们把1减去3,就得到方程4。

当然还有做一下稍微做一下移项,那我们可以得到A deform减去C deform,等于什么f乘上A rest减去C rest,类似的我们把2减掉3,可以得到方程5,对吧,这是个很简单的一个关系。

我们把4和5搬过来,这边变成6和7,那么我们现在得到这两个方程组,注意它每个都是一个向量方程,每一个它其实就是左边是一个二维向量,右边是一个二维向量对吧,那么你加起来一共就有四个线性的约数。

linear constraints,或者叫四个线性的方程,OK那么我们其实就可以把f里面的所有的项,全部都给它求出来了,对吧我们可以把f里面所有项全部都求出来,怎么求法,首先我们构造一个矩阵叫做B。

对吧这个B它其实有两列,第一列是A rest减去C rest,第二列是B rest减去C rest,那么这就得到一个二乘二的矩阵,我们把它取一个逆,然后我们还有构造一个矩阵D。

这个D是A deform减C deform,然后再加上第二列是B deform减C deform,那么我们就其实可以看到这个f其实有这么关系,f等于什么,f等于D乘上B,它是这个矩阵乘法。

这边还有一个性质,就是说你的这个B它是一个,在整个物理过程中它是一个常数,为什么呢,因为它只和你静止状态中三角形的,三角形元素的三个顶点的位置有关系对吧,所以呢我们会把它提前算好。

提前矩阵求力给它求好然后存着,你可以看到这个矩阵求力还是一个比较,比较costly的操作,至少你得算一次出法对吧,你得算determinant它的倒数,得算一次出法,这个还是比较costly。

所以大家一般会提前把它算好,然后存在内存里面,要用的时候再把它取出来,OK那么我们现在有了刚才这个关系,其实我们就知道怎么算一个element,它的deformation gradient。

那我们现在可以很容易地写出来一个,显示时间格式的,这么一个时间积分对吧,那么我们一般情况下,大家是不用forward Euler,大家一般是用semi-inclusive Euler。

或者这个又叫做Sympathetic Euler,注意它虽然叫做semi-implicit,它是一个显示格式,这个semi-implicit是一个被abuse的一个词。

有各种各样的东西都可以叫做semi-implicit,然后你先更新V对吧,然后你再更新X,那么现在的问题是,你看看这个方程式里面,其实唯一的一个未知数是什么,这个里面不知道的是这个FTI。

FTI怎么求它呢,这个求起来其实非常容易的对吧,我们有这么个关系,就是说顶点的位置是势能,顶点的上的受力是势能,关于顶点上的顶点的位置的导数,再取一个负对吧,这个是一个很常用的一个关系式。

那么我们刚才已经讲了,对于三角形的元素,它的线性元素,它的Ue我们是知道怎么算的对吧,然后我们把每一个元素的Ue加起来,就得到了整个弹性物体的U,OK就是说,总的弹性势能等于每一个元素弹性势能之和。

那么我们再把这个符号移到这边来,然后我们再把这个展开一下,那怎么展开呢,我们把这个Ue,Ue其实等于什么,我们刚才回顾一下这个公式,Ue等于Ve乘上Psi Fe,OK,然后这边替换以后再用劣势法则。

OK,然后这边就多出来一个元素的静止状态下的体积,注意这个是静止状态下的体积,这不是形变以后的体积,所以这个其实也是一个常数,然后求了以后你发现这个是一个什么,这个是Pk1 stress对吧。

这个Psi对于F的导数是Pk1 stress,然后还有一个F它的形变剂度,关于X导数,这个有一个求导的过程,大家可以去手动推一推,那如果你不想去计算这个Psi F,你不想计算F对于X导数怎么办呢。

你可以用太极的自动微分系统,如果你用太极自动微分,那你后面就不需要理解了,你只需要知道,只需要懂到前两个等号就可以了,后面就不用管了,那么这一讲后面我们会讲一讲自动微分,但是我这边可以先给大家看一看。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

怎么来实现这个,在太极里面怎么实现这个显示的Fem。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到我这边其实,我并没有一个计算受力的一个函数,我只有一个计算总的弹性能量的一个函数,我这边用的其实是一个什么,是一个neo hooking,用了一个neo hooking的材料。

这边注意一下我把J和0。2取了一个max,这样就防止你的J变成一个接近0的数,这个neo hooking有一个什么很明显的问题,它这边有一个log J对吧,log J的话你这个J如果是负数的话。

你这个整个simulation就会挂了,就会出现各种infinity啊not a number啊,之类的数,那这个就整个就非常不稳定,所以这边我就为了让它稍微稳定一点,我把它和0。2取了一个最大值。

不让它变成接近0,OK,那么我们把总能量计算出来以后,你可以看到我在哪儿调用了这个compute total energy呢,我这边用了一个ti。tape,ti。

tape其实就是太极里面的这个自动微分的,你可以认为是它的磁带,在tape里面这些东西我们会把它记录下来,在执行这些函数执行完以后,我们会进行backpropagation,也就是说求导数。

求出来导数以后,那么导数在哪儿被用上呢,导数其实是在应该是在这个地方被用上,我们在做semi-implicit order的时候,我们把x的负导数,这个其实是总能量关于x导数的负值。

我们把它除上你的质量就得到它的加速度,我们在进行这样一个积分,其实就是在太极里面非常容易实现,因为有这个自动微分的其实,其实整个程序有100多行。

其实mass spring system可不可以用自动微分呢,完全也可以,只要你是你能定义出来一个势能,你就可以进行自动微分,其实我这边还,你可以看到我这边还有一个重力的这么一个项。

这个是一个负g乘上dt的积分对吧,我其实完全可以把我的重力,重力是也给它加到总的能量里面,然后整个全部交给太极自动微分,这样你就不用手动的去求这些乱七八糟的东西了,这个求导这个过程是非常非常头疼的过程。

我以前花过很多时间浪费在求导数,以及检查我推出来导数到底哪错了,这么个问题上面,现在有自动微分以后,这个求导大家就不用去头疼了,OK,大家可以我这次实在有点出忙。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最近事情实在有点多比较忙,所以暂时还没有来得及把这个科建这些代码上传到网站上,但是上结束以后我就会上传这些东西,OK,那么刚才讲了显示时间积分,那么我们看一看影视的时间积分,那么大家可以回顾一下。

之前我们讲过一个看起来稍微有点复杂的公式,就是这个backward Euler的这个影视时间积分,然后其实我们得solve一个linear system,如果我们用一次Newton Rapsom。

我们其实在局部做一个一阶段的展开来建立这个方程,就可以得到什么,得到一个我们这个公式11,那你看到这个公式11里面就头疼了,你就有了一个偏f偏x这么一个项,f是什么,刚才我们推出来这个f大概是一个。

Psi关于你的x的导数,那你这边又把它对x求一次导数,那你就要求二阶导数了,对吧,注意我这边好像是不是有一个tackle,这边应该是偏x平方,这边显示偏f平方,然后求这个二阶导数。

这个叫做force differential,这个就求起来就非常头疼了,我刚才提到如果说你在三维里面的话,你往往是要求一个你中间过程中,可能会用到这个Psi关于f的二阶导数。

这个是一个三维里面其实就是一个81个元素的四阶张量,这个算起来就不是很友好,那很遗憾的现在太极自动微分还不能求二阶导数,所以大家还是要这边还是要手动推一下,如果不想手动推可以去看我提到的两个教程。

它里面有各种各样材料的这个二阶导数,其实两个教程写得非常清楚,你可以照着它写,当然你照着它写你会发现就算公司告诉你,你自己去写还是挺麻烦的,这个我得坦白说我自己也写过,不是特别容易写很容易写错。

这就是为什么我建议大家组队,因为你组队以后你就可以相互检查,这些代码其实很多时候你可能10%的时间在写代码,90%的时间在debug你的代码,如果你一个人写另外一个人看着。

或者一个人写另外一个人review一下,你就可以发现很多别人的错误,那你可能一眼就看出来了,因为其他人看你自己做的事情,你可能当局者迷旁观者清,你可能别人一眼就看出来你到底哪写错了。

所以这个合作其实能很大程度上提高你的生产力,那么剩下来最后一个问题怎么去求M,这个M上次有同学问这个M是什么,这个M其实就是一个质量的矩阵,它是一个对角矩阵。

然后它的每对角线上每一个元素就是这个load的质量,那在FVM里面其实这个M它就,M矩阵还有点复杂,它需要用一个叫做mass lumping的技术,把这个F给它简化。

那么在graphics里面大家一般不care,你这个M你可以用任何你觉得方便的approximation,你甚至就可以把它设成元素的质量,你可以把它设成元素质量,然后当然你也可以设成这个顶点的质量。

是周围元素质量的一个加权以后得到的东西,那你也可以这样设定,你可以用任何你觉得方便的近似,OK,那么这就是我们今天的第一部分,好像一不小心准备的科技有点多,我们可能第二部分稍微加速一下。

那么我们有什么问题吗,可能这部分稍微有点难,但是大家不要担心,因为就算你不懂,你看代码你也会知道这个东西应该怎么写,像各种stress tensor,其实虽然我讲到了它们的定义。

但是我们其实用到了PK1 stress,刚才有同学提到这个PK1 stress,它不是对称的,这个其实很容易理解,因为你可以从这个关系来看到,因为你的true stress tensor。

因为角度量守恒它是对称的,这个sigma是对称的,那你把它乘上一个f的负转制,那f本身又不是一个对称的东西,那它这个乘上这个矩阵当然就不是对称,那么对称的版本是好像有一个叫PK2 stress。

好像是对称的,但是这个PK2用了就更少了,OK,tau是对称的,tau是这个j乘上sigma,j是一个常数,常数乘上一个scalar,scalar乘上一个matrix,乘上一个对称矩阵。

得到的还是一个对称矩阵,那么大家有什么问题吗,我们可以现在回答一下,我看看现在有没有什么问题,可能大家会觉得这部分涉及的连续介质力学有点多,但是这其实都是比较简单的连续介质力学。

真的连续介质力学会比这个难很多,然后我这边其实如果一开始有点搞不清楚,其实完全没有关系,因为我一开始我是学计算机的,我一开始也不太搞得清楚这些东西,然后后来我是通过写代码来学习这些东西的。

所以大家不用特别看到这些不用特别紧张,这个搞不清楚顶多是多调试一会儿,行那么我好像也没有看到特别多的问题,OK, Autodef怎么用我后面会讲。

然后有同学问要不要组装这个Stiffness Matrix,这个其实Stiffness Matrix主要是在Inclusive FEM里面,才需要去组装它,这个后面我们会讲到。

这一讲因为内容已经非常多了,我不能再讲太多,再讲太多估计大家都退学了,都不来上课,我知道有些同学可能是专业的力学专业的,所以听的反而还会可能觉得还比较简单,但是毕竟这个课是一个全连领的课程。

所以我们不能讲一些过于粗暴的概念,OK, 我们照顾照顾到所有的同学,如果大家觉得吃力了可以课后,再花点时间去看一下我提供的两个教程,两个教程其实都是从计算机的角度,从图形学的角度来考虑这些东西的。

所以还是比较容易理解的,那么我们其实今天好像时间有点多了,时间有点长了,所以我们第二部分我们就稍微讲快一点,OK, 那么第二部分我们讲一讲,太极编程语言的一些高级的feature。

这部分其实就比较简单一点,这个部分可能更照顾学计专业的同学,刚才那部分可能照顾一下学力学的同学,当然我可能讲的不是很严谨,如果学力学同学有专业的背景,看出一些问题的话,也可以在论坛指出一下。

这样大家能学得更好一点,我自己也是一个学习的过程,我在做slides的过程中,我自己也把这些,我其实发现自己很多知识的盲点,我也把它再补充了一下,我这个讲课其实也是一个很好的学习的过程,OK。

那么我们讲一讲高级的太极feature,我们今天讲讲几个简单的概念,在这个太极里面其实可以做面向对象的编程,其实大家教的作业里面,其实有很多已经用上了class对吧,然后我们还会讲一讲原编程。

就是template, 母版,然后一些重用代码的各种各样的技巧,我们还会讲可谓编程,刚才已经提到了一些可谓编程,可谓编程其实就是可以,比如说你可以求导数,求导数可以用来算什么呢。

可以算你的势能关于位置的导数,可以算出来是什么,其实就是你的受力的负值对吧,我们最后会讲讲三维格式化,在过去一周我们助教团队做了一个非常厉害的事情,就是说让太极可以输出POY格式。

POY是可以包含三维的粒子,三维的网格,然后有了这个POY格式,大家可以在太极里面做三维的模拟,然后输出成POY格式,然后在三维软件里面把它打开,然后进行各种各样的查看渲染之类的操作。

太极本身提供的图形系统主要是为2D而设计的,OK我们先讲讲面向对象的编程,太极是一个面向数据的编程语言,但是这个DOP虽然在很多时候它的性能会很高,但是你要模块化它就比较难了。

那么为了提高这个代码的reusability,太极就从OOP里面面向对象的编程里面介入一些概念,这样我们达到一个混合的scheme,我们叫这个scheme叫做ODOP。

Objective Data Oriented Programming,然后有三个非常重要的decorator大家可以使用,如果你的class是一个面向数据的class。

而不是一个普通的python class,就是说你要用ti。dataoriented去修饰你的太极class,对于普通python class你就不用修饰它,你只要用一个太极的class就这样去修饰。

不好意思我好像总是喝水,感觉好像讲了口干舌燥,讲了来劲了就口干舌燥了,然后我们可以用ti。kernel,如果你这个class member它是一个太极kernel的话,你就可以用ti。

kernel去修饰它,如果你的class member function它是一个太极的function,你可以用ti。function去修饰它,那么以前我们是没有这么方便的,我们有ti。

classkernel和ti。classfunction,现在我们已经不用了,如果大家看到以前代码里面有这样的东西,其实可以自动忽略它,这样我们已经不用了一些了。

这个背后有一个很长很长的development story,这个是匡冶大神写的一个太极机器开发的故事,还是很有意思的,这个其实你可以看到,为了我们大家能用上ti。kernel,而不是ti。

classkernel,背后的工作量有多大,真的开发一个编程语还是一个工作量非常大的,一个很辛苦的工作,不过我认为是非常有意义的,大家如果有兴趣或者对python想了解更多的话。

可以去看一看匡冶大神的这个post,那么接下来我们讲一个最简单最简单的例子,这是一个行星绕日系统的这么个例子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我其实可以跑一下,这个叫做什么来着,odop solar,对了太极已经升级到0。6。10了,大家可以去更新一下自己的太极。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因为这个例子是0。6。10才有的,跑上在另外一个屏幕跑没看到,它其实就是一个很简单的一个例子系统,对吧中间有个太阳。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后有几个行星绕着这个太阳转,其实是一个很简单的一个东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你如果看到代码呢,就在这看吧,你会看到代码你会发现我写了一个class,这个class叫做solar system,然后我用一个tie。dataoriented,to decorate it。

我用这个东西去修饰它对吧,然后你可以看到这个class里面有很多个tensor,这个tensor我们就把它作为成员tensor来处理,其实和你在外面写没有任何区别了。

唯一的区别就是多了各种各样的self对吧,但是你一旦写成class以后,你的这个代码的可复用性就变高了,你下次在用的时候,你只要定义一个solar system,这样一个instance就可以了。

我们可以看到呀,你的这个class的function,tie。function可以被一个额外的static method去修饰,就是静态函数,这个其实这个python里面的static method。

是含义是一模一样的,这边呢我定义了一个static method,这边是其实就生成一个范围内的随机数,然后呢class里面kernel,其实也和外面的kernel一模一样。

唯一的区别就是它带一个self,这个其实就和python里面的class的函数,和外面普通的函数的区别一样,ok,那么我这边还是在这个class里面,我又定义了一个function。

这个function不是一个static function,所以我直接用tie。function去修饰它就可以了,我还有一个integrate kernel。

这个其实就是一个simplectic Euler,我去积分它,怎么用这个class呢,也很简单,跟用python class一模一样,我们只要定义这个solar system,然后这个9。

9应该是你看到这个class,它的constructor take两个参数,一个是n,n是行星的数量,然后dt是time step size,ok,然后我们还可以直接指定class里面tensor的值。

这边我把它中心设成0。5,可以调class的kernel,就和调class function,和调普通pythonclass的function一模一样,那么这个还是一个比较简单的程序。

大家可以自己跑一跑,自己写一写太极的class,当然之前交出来的很多作业上面,大家已经自觉地使用class了,用class以后你代码就可以重用了,你甚至可以在一个文件里面实现这个class。

然后在另外一个文件里面去调你的class,这样你可以至少多文件了,对吧,你如果用kernel和function的话,多文件就是比较麻烦的一个事情,多文件的话你每个文件就会小一点。

这样你维护起来成本就比较低,刚才有同学问keyeditindit能不能变成kernel,这个地方暂时应该还是不行的,我其实从来没试过,你可以试一下,但是我从来没搞过这种用法,我猜应该是不行的。

但是一般keyeditindit里面不是去初始化你的tensor,而是去定义各种各样的tensor,它定义了各种memory field和kernel,然后这边真正的初始化是initialize。

它会初始化你的所有的tensor,OK,接下来我们讲讲原编程这部分,我可能得快速地过一遍,然后后面我们再细讲,因为现在已经一个小时了,太极提供很丰富的原编程工具。

原编程工具可以让用户pass几乎所有的东西给太极的kernel,然后它还可以提高太极kernel运行时性的,因为做了原编程以后,你很多时候一些量在编译期是知道的。

所以你就可以把你的运行时间的开销移到编译时间,原编程还可以让你实现维度无关编程,这个听起来非常疯狂,就是说你可以把二维和三维的模拟代码写在一起,二维和三维的模拟代码写在一起。

你可以如果想一想我们其实FEM里面,二维三维其实非常像对吧,那其实只有唯一的区别就是,二维相量三维相量三角形四面体这么个区别,二乘二矩阵三乘三矩阵这么个区别,其实可以用原编程的话。

你很容易实现维度无关编程,这有什么好处,这个好处在于你调试的时间就缩短了,因为你只有一份代码,很多时候你把二维的搞对了,然后三维的自动的也就对了,这个大家以前在写C++的时候。

一般会用模板原编程来实现二维和三维写在一起,这个其实就C++里面也可以做到,但是比较费事,太近就非常方便,这个我们后面会讲具体怎么来做维度无关的处理,然后原编程还可以提高简化太极的标准库的实现。

其实太极的标准库,比如说什么tunampi这些,其实很多都是用原编程来写的,太极的kernel其实它是懒惰初始化的,那么懒惰初始化有什么好处,就是说你如果定一个kernel你不去用它,它就不会被编译。

然后刚才不应用初始化应该叫实例化,instantiation,很多计算其实可以在编译时间完成,你在编译时间把计算完成了,那你在运行的时候你就可以少花点时间,大家一般还是更在乎运行时间而不是编译时间。

当然现在太极可能有些极端情况编译有点慢,所以大家可能更在乎编译时间,但一般情况下编译时间都是很快的,那么其实你在写kernel的时候,每一个kernel在太极里面都是一个template kernel。

它唯一的区别只是它有多少个template argument,大家现在在用的太极kernel它也是template kernel,它也是template kernel。

但是它有零个template argument,OK,这个我们后面会仔细讲,我们看看这个kernel,这个kernel叫什么,这个kernel叫copy,这个kernel做啥呢。

你可以pass给它两个tensor,那么注意我们这边用的type hint叫做ti。template,这个地方一定要把两个括号加上,你括号不加它可能会有编译错误,这个c是一个ti。f32。

然后我们做什么事情呢,我们把yi设置成xi加上c,那你会发现这个kernel你去调查的时候,你就可以pass两个eway的tensor进去,当然它们大小最好得一样,然后再加上一个offset值。

那么你如果说不用template的话,你就很难把tensor当成argument pass给这个kernel,OK,这个还是比较容易理解的,大家可能在写simulator的时候,可能已经有这样的需求了。

那么知道这个template怎么用,就会少写很多代码,那么除了tensor你还可以把class,以及class instance,或者你的function,或者各种numerical method。

numerical value pass给你的ti。template,但是这个要注意一个问题,就是说它的template kernel instantiation,是overhead比较大的一个操作。

比如说我这有两个函数,一个叫hello一个叫world,对于hello的kernel,它的i是一个ti。template,也就是说它可以take任何东西,并且你传给它不同值的时候。

它会被instantiate,OK,那么我如果说for i in range 100,然后我调hello i的时候,它这边其实就会创建100个不同的。

hello这个kernel的instantiation,那么我如果下面再来一趟,for i in range 100,然后hello i,我如果把这个部分重再重复一遍,它就会reuse第一次创建出来的。

这些100个不同的kernel,对吧,这个就是template kernel的行为,那么如果说你这个不是template argument,你这是一个普通的ti。i3。

就这么一个简单的整形边档的argument,那么这个kernel它就不会被instantiate很多很多遍,因为你这个i32它是一个数值值,而不是一个模板值,OK,所以它只会被创建一个instance。

在这个use case底下,大家其实world这个函数比hello更好一点,对吧,因为你毕竟hello生成了100个不同的kernel,但这个函数是很简单的函数,你真的运行这个程序你会发现性能差不多。

但如果你这个hello是一个非常非常复杂的函数,那你可能性能上就会有差异,因为它得编译100遍,很多时候编译100遍时间还是挺长的,那么另外一个很有用的feature,是叫做这个维度无关编程。

什么叫维度无关编程呢,刚才我们展示了一个copy这个kernel,刚才我们的copy kernel只是对eway的tensor有用,那如果我希望做这么个操作,我把y的所有的值复值给对应的x的上面的值。

但是我这个xy可以是1d tensor,2d tensor,甚至是0d tensor,它是一个0维的tensor都可以,那么怎么办,我们有这么个语法,就是for这个大写的i,这个大写小语无所谓。

我这只是convention我用一个大写,重要的地方是什么呢,重要的是ti。grouped,我这边其实把y的index全部拿出来,进行了一个打包操作,打包操作,那这个i其实就是一个n维下量。

如果你的y是一个nd tensor的话,那这个i就是一个n维下量,这个tensor index你就可以直接把整数型向量传给它的,所以你就可以写这个xi等于yI,这有什么好处。

这个kernel对于不同维度的tensor,维度不同大小的tensor都可以work,你就少写代码,那么还可以做一些更fancy的操作,比如说我们可以写这样的一个kernel。

注意这个i实际上就是一个普通的vector,你可以把i的第0个值或者第1个值给它拿出来,然后做一个复制,那么这个i0其实就相当于i,i1相当于j,如果你的x tensor是一个二维tensor的话。

我们在运行时,我们在编译期还可以进行tensor size的reflection,我们可以在编译期获得tensor的大小的这么一个,怎么说这个叫tensor大小的反射,我就用reflection吧。

这个翻译成中文实在太奇怪了,一般很少听人说反射,反射是什么呢,反射就是你在程序检查自己的自身的一些行为,也叫inspection,叫自省,可能自省好一点,就是你在编译这个kernel的时候。

你可以去查询这个tensor到底是几维的,然后这个tensor的shape是什么样,大家可以运行一下这个程序,这个可以打出来一个x tensor的shape,OK我们还可以做编译期的branching。

编译期的分支,这个compile time evaluation,这个地方其实允许我们在做一个没有运行时overhead的branching。

比如说你可能你的程序里面有一个enable projection,你可能projection可能是比如说碰撞处理,你可以让它这个projection变成处理碰撞,也可以变成不处理碰撞,那怎么办。

你可以用一个ti。static,修饰这个enable projection,在你这个if branching的condition里面,这样它和if enable projection的区别就是。

if它的static enable projection,它的这个branching是在编译期进行的,如果你用C+17的话,你就相当于在用if constexpert,对吧,它是没有overhead。

那么这个ti。static用处非常多,我们还可以用它来强行unroll你的for loop,就循环展开,你可以在编译期循环展开,那么这边是一个例子,这个例子其实就是说,我去fail这个tensor。

这个tensor是一个向量的tensor,向量的tensor它是一个三,它的每个emma是一个三个向量,那么我这边可以做一个什么操作呢,我对这个tensor里面每一个元素,每个向量我把它复制成012。

那么我就可以写这么个static for loop,它是一个强行展开的一个for loop,强行展开呢其实有很多的用处,对吧,你循环展开以后,你可能首先你可能会希望它性能更高。

因为你loop unrolling以后,你就可以减少loop本身的overhead,对吧,你可以希望得到更高性能,这个时候你会希望用到循环展开,你还可能会希望去loop over的东西。

不是tensor的indexes,而是还是你的tensor里面element的indexes,也就是说你的向量或者矩阵的下标,注意太极有一个限制,也就是说太极里面的向量和矩阵的下标,必须是编译期的常数。

这个可能有一点难以理解,就是说你每次访问一个scaler的时候,你得先做什么操作,你得先去从tensor里面拿出tensor里面,这个element是一个向量或者矩阵,对吧。

然后你再来一次indexing,这个indexing是取出向量或者矩阵里面的,那个scaler元素,那么第二步它的下标就必须是一个编译期的常数,这个我们在太极一开始设计的时候就做了这样的设计。

然后这个是一个limitation,但是大部分时候影响不大,如果你真的要去访问它的matrix或者vector元素的话,就得用一个编译器的常量去访问它,但是如果说你这个是个循环变量怎么办。

你就得unroll这个循环,这样你的unroll出来的结果以后,你的循环变量就变成一个变异常数,这可能稍微有点绕,但大家可以看程序以及通过编译错误,自己很快就能体会到为什么要这么搞。

OK我们还可以做一些variable aliasing,为什么做variable aliasing呢,其实就是说有的时候你的一个变量的名特别特别长,你希望在局部给它做一个reference。

你给它做一个短的版本,比如说我们有这个kernel,它是一个比较简单的kernel,它做什么事呢,它是把这个tensor A里面每一个下标取出来。

然后把tensor B的对应下标设成一个function,在apply在tensor A的对应元素上面,你可以看到它是非常长的,我们可以做一个variable aliasing。

做了这个aliasing以后,就可以变成A B function等于tiding static,然后我们相当于在tensor A tensor B和some function。

给它create了一个aliasing,然后这样我们就可以在用它的时候,就可以用它的alias用它的重名,叫别名,用它的别名就会方便一些,这个地方这个例子其实不是特别好,因为A和B这边只用了一次。

很多时候比如说你要写一个stencil,那你这个A可能比如说是一个5 point stencil,5点的stencil,你就可以A在这个kernel里面出现了5次,那你不能每次都写个tensor A。

那就非常的长,你可以就把tensor A先缩短到A,然后你下次就用A就可以了,这样就比较方便,注意这边一定要用tiding static,你不能直接写A的tensor A,那就会出现一些问题,预防错误。

这个还是tiding static已经被用了在很多很多地方,OK那接下来我们讲一讲可谓编程,什么是可谓编程呢,我们之前讲的程序,大家一般意义上的程序,它都是在evaluate一个给定输入。

给你一个输出对吧,算f其实是算这个f of x,给定的x算f of x,然后可谓编程求什么呢,可谓编程它,你可以认为它求的是fx,关于x的偏导数,或者叫jacobian。

太极支持reverse mode autodiff,这个叫反向模式自动wav,可能名字有点长,但是大家如果觉得confuse,其实没有任何关系,因为这个不是特别重要的概念,如果你作为用户的话。

你只要知道怎么用就可以了,它可以做啥呢,它可以反向传播,它可以把你的loss function,就是这个fx,它是一个scalar function,它的导数,关于每一个元素的导数,给它计算出来。

ok这个非常有用对吧,我们刚才已经展示过,如果说我们在求力的时候,我们就可以用自动微分来求出力,而不是用手动的求导求出力,那么有两种方式可以去求导数,第一种方式用太极的tape,你就用一个with。

tied up tape,然后loss equals something,这样你就可以去记录你的forward kernel,然后它会自动的,它会自动的求这个backward kernel。

这个是全自动的,但是有的时候你可能希望有一些控制,更多的控制,那你可以用gradient kernel,这个后面我们会讲,今天时间关系,我们就不继续讲了,这边有一个非常非常trivial的例子。

这个例子干啥呢,我们定义一个loss function,这个叫l(x),x是一个向量,这个loss function算啥呢,算x和y的差的平方的和,再乘0。5,ok那么这个其实你可以算出导数。

这个导数就很trivial了,这个导数其实就是,就是x对吧,你l(x)对x导数其实就是x,那么我们怎么用可为编程来做优化呢,这个其实很简单,我们首先allocate这个tensor。

在allocate tensor的时候,你要记得加上一个needs gradient equals true,这样它才会求出l关于x的gradient,这个一定要注意。

如果你没有needs gradient等于true的话,它就不求gradient了,因为很多时候你并不需要求gradient对吧,那么我们定义这个loss function。

我们这边只要定义forward就行了,这个loss function基本上是一一对应对吧,很容易,我们reduce这个signal其实就是算l(x),然后它其实就是把这个差的平方乘0。5。

然后全部accumulate到l上面,这边要注意太极里面的加等于号,这个是一个原子的加等于对吧,ok那么接下来呢,我们就在这个tape的这个作用域里面,我们在python里面用with tie。

tape loss equals l,then we do reduce,然后我们调了这个reduce其实是forward对吧,那么在tape生命周期结束的时候,它会自动做backward。

backward是什么,backward就是给你求出x。grad,这个地方我们做一下gradient descent,做了这个gradient descent以后呢。

你可以把x更新到一个更加接近于真实值的x,记住下降对吧,做optimization的一个比较简单的搞法,这个我应该可以demonstrate一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个叫做autodiff minimization,看还能不能跑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好可以跑,你可以看到这个demo比较无聊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它就是是一个trivial的demo,它就是你看这个loss function在不断的下降对吧,l2 loss加上定长度的gradient descent,它是一个指数下降的一个过程。

所以它收敛的非常快,对其实还有一个feature叫做example-p,这是彭于冰小朋友贡献的这个feature,这个feature非常有意思,你可以example-p就可以把这个,把你的这个函数。

把你这个example给它打印出来,还有一个大p,大p是干啥呢,大p是会把它以一个语法高亮的形式打印出来,这边大家要装一个叫做rich的包,这边我应该没有装,所以它现在应该还不work。

但是我可以装一下,rich实际上是一个语法高亮的包,这是一个很有用的一个功能,ok应该现在能work了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对这个是应该是sublim text的语法高亮了,这个打印出来就非常漂亮,大家可以用用这个-p和-s。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

-s就可以把你的demo存在你当前的目录底下,所以还是很有意思的,就很实用的功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok这是一个比较简单的demo。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大家可以看一下这个函数,其实这个程序其实非常简单,对吧,你就是唯一一个需要学习的地方,其实就是这个tie。tape,对吧,你可以创建一个磁带,这个磁带记录你的curl launch。

然后launch完了以后,以颠倒的顺序去调这个curl的gradient,所以你就可以做这样的一个求导数的操作,这个非常简单。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还有一个example叫做,autodiffminimization。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

叫做regression吧,我记得它是一个,应该是一个三次函数回归。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后也是用一个非线性的三次函数回归,然后我们用三阶动向式来fit这些数据点,然后也是用这个,t路下降来求出来的,ok这个其实也比较容易。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我也可以再演示一下这个杠皮。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个color scheme还是很有意思,你可以看到也就八十几行代码,所以如果大家想fit曲线的话,也可以用太极的autodiff的feature,定义一个能量函数,然后用t路下降。

也可以做到这个不错的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok我们继续,那么刚才讲到了这个可为编程有两个application,先讲第一个很简单,之前我们已经提到了,我们可以用可为编程求出potential energy,关于位置的导数。

这样我们就知道顶点的受力对吧,其实这个地方用了可为编程,主要是简化我们的数学上面推导,我们就不用去推这些导数了,其实还有刚才我主要演示的是一个fem的example。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实还有一个npm的example,我们可以run一run,这个是一个npm里面的叫laglang-relead的一个模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它其实和fem非常非常像,为什么这么卡,这个程序可能主要是可是化非常卡,一直也没搞清楚为什么,但是其实算的还是很快的,主要是画出来非常卡,这个其实和刚才fem非常像,但是npm由于有一个背景网格。

所以它能够额外的在做一些背景网格上面的碰撞处理,刚才我们看到fem其实很容易有自相交,这个自相交非常非常头疼,这个处理起来非常讨厌,但是npm里面它自己和自己相交的话。

它会在背景网格上面进行一些自动的碰撞处理,这样你就不用去显示的去处理它的碰撞,那么这个是npm的一个lagrangian forces的一个model,这个后面我们会细节我们会在npm的部分继续讲到。

大家可以自己去跑一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个其实计算应该是60fps,但是不知道为什么可是化比较慢,可能跟我开始直播也有关系,那么第二个application,你可以如果你手动的把你的收力球出来,你的每一步里面没有用到auto diff的话。

你就可以把这个auto diff省下来,来求整个物理过程的导数,那求出整个物理过程导数有什么用呢,你可以去做很多的物理系统初始状态的优化,或者说你可以做一个物理系统里面控制器的优化。

controller的优化,这个很有很有意思,我们可以看一看这个diff-touch这个项目,这个是我之前做了一个研究项目,但是现在基本上这个已经非常成熟,这个每个人都可以两三个小时,如果你熟练的话。

两三个小时就可以写出来一个可谓的物理模拟器,这个其实就是说你看这是个机器人,然后他有两条腿,每条腿上面有两块肌肉,你可以通过他这个肌肉的收缩和拉伸,他就可以把这个腿就把它相当于迈开腿。

迈开腿以后就可以往右边动,这个控制是用神经网络来控制的,这个神经网络如果在没有diff-touch的时候,你得用这个reinforcement learning,这个增源学习去学习这个神经网络的权重。

那这个效率就非常低,你有了diff-touch以后,你可以用t2下降来优化,刚才我们说了t2下降,由于导数导向性非常非常强,你一般来说这个一二十个iteration以后,你就基本上能动了。

我们看一看好几个demo,这个是一个2D的demo,用npm加上diff-touch。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

differentiate整个npm的过程,然后就可以让这个机器人朝前走。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个是一个三维的版本,npm可以自动的处理水和elastic object的这个偶合,所以你就可以给他加上一些水,这样他移动就慢一点,但他还是在朝前移动,还可以做什么呢。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们还可以求一个,这个应该是一个height field,一个water simulation,然后白色表示他这个水面更高,黑色表示水面更低,你可以认为它是一个水波大量的模拟。

那么我们可以求一个初始的水波,使得经过一些time steps以后,它可以形成一个态极的pattern,相当于我们在求一个反向的一个模拟,我们去求出一个初始条件,使得这个初始条件经过模拟以后。

能得到一个态极的pattern,那么我们还可以把它和,我们可以之前一段时间有一个非常流行的,一个东西叫做神经网络的对抗样本,我们可以求一个初始的水面height field。

然后我们用DeepTouch做了可微的水面模拟器,再加上一个可微的水面渲染器,再加上一个可微的神经网络,这么一个三阶段的可微程序,我们可以求出来一个什么,我们可以求出来一个水波,使得这个水波的折射。

加在这个松鼠的图片上以后,VGG就是一个图片识别网络,VGG认为这个松鼠图片是一个鲸鱼,而且它的信心相当高,它说这个松鼠经过我的这个水波以后,99。91%是个鲸鱼,这是一个对抗样本。

就是说神经网络它有的时候,它的鲁邦性不是特别好,如果你知道它的导出的话,你可以做一些攻击,这个是可微的钢体物理模拟器,你可以看到这个是个机器人,然后它也是各种弹簧,然后这个弹簧去拉动它就会朝前走。

这个是个弹簧指点系统,这个是一个比较简单的弹簧,这个其实收敛非常快,一般一二十个就收敛,大家可以下载下来跑一跑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个是机器学习打台球,我们优化白色球的初始位置和速度,这个蓝色球最后能到达这个黑色点,OK,这个就是我们之前写了10个。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Differentiable Simulator,证明这个Diff-tie其实是一个可用的东西,对,然后这个注意,如果你写可微编程程序的话,你就得去分配每一个time step,你都把它记下来。

你不能只开一个time step的这个tensor,来记最新的time step,你得把整个time step,整个模拟的过程全部都记下来,所以说这个内存占用一般是比较高的,比如说你本来是。

你如果有n个particle,那你开一个e位的tensor就可以了,你把每个tensor的位置开一个e位的tensor,每个particle的位置开一个e位的tensor,但是你如果用可微编程的话。

你就得开一个二位tensor,这个tensor它的第一个dimension,是你有多少个时间步,然后第二个dimension才是你的有多少个particle,就开一个二位tensor。

如果说你觉得这个空间占用过大了,你可以用checkpointing,这个是一个autodiff里面一个常用的技术,checkpointing可以把在你的计算,你本来计算是on空间是on嘛。

你用checkpointing你可以把它降到,比如说空间是o1,然后计算是o√n或者o3次的√n,那集装情况下你可以把空间缩到olog,然后计算缩到这个nlog,我刚才说错了。

刚才说你可以把空间降到o√n,然后时间降到o,或者你空间可以降到o,三次的√n时间降到o,就是说你空间本来是o,所以你空间是可以降低的,集装情况下你可以把它空间降到olog,然后时间变成应该是nlog。

对吧,你可以用空间换时间,最后我们讲讲太极的visualization,那么之前大家很多时候,我发现有些东西上交上来的作业,它上面2D的result是用opencv,或者用一些别的库来渲染。

那样的话也不是不行,但是太极就内部提供了一些非常方便的,可视化的一些功能,叫做ti。gui,然后你可以创建一个分辨率是512的窗口,然后title叫做太极MLSMPM128,然后你可以指定一个背景颜色。

你可以在这个gui上面画圆圈,也可以画线画三角形,然后也可以指定一个image为它的tensor,然后呢,你也可以把这个gui展示到屏幕上,这部分呢我就不多说了。

大家可以去看各种各样的sample code,以及看看文档,那么值得多说一些的是,怎么可视化你的三维结果,这个很多同学已经迫不及待地想从二维一到三维了,所以助教团队上周进行了非常非常辛苦。

非常给力的开发,开发了一个叫py。pywriter。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大家可以去看文档,这个文档里面呢,他会讲到怎么去输出py格式,py格式是一个可以二进制,可以人类可读的一个三维数据格式,然后开py以后,你就可以用Houdini把它打开,我们这边演示一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们跑一个exportpy吧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到它在当前目录底下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就出现了这个example。py好多个对吧,那么我们怎么来看它呢,首先你可以看example。py,它里面的内容,它有一个header,过了这个header以后它就是二进制的。

所以这个存储效率是比较高的,当然你也可以可选性的输出这个ASCII格式,就是人类可读格式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们用一般来说我们搞simulation的话,是用Houdini来打开这些东西,大家可以去装一个Houdini,Houdini的这个学徒版是免费的,还是非常好用的,Houdini呢可以在官网上下载到。

然后各个平台都是支持的,顺便说一句Houdini是现在在电影工作室里面,非常非常常用的一个特效制作软件,它本身就可以做各种各样的模拟,OK,你看这是一个比较重量级的软件,电脑已经连接到了。

我们怎么来引入刚才的这个PY文件呢,点一下这个file,点一下import,然后点一下geometry,OK那么我们到刚才这个文件夹,应该是demos,你可以看到这边它就自动识别了这个examples。

它是一个序列,我们把它打开,这个怎么就无限菊花了,这个要等好久,大家正常电脑上是不会等这么长时间的,我这个电脑因为时间负载比较重,我们刚才看到这个应该是多少帧,这个是9帧10帧,所以我们底下这个时间轴。

我们可以把它改成0。9,这个可能得在这改一下,OK,然后你去拖动这个进入条,你就可以看到这个粒子是在动,我这个电脑可能不太正常,正常情况下你去拖它,这个动画是非常非常smooth的。

然后你点一下这边的播放按钮,它就可以播放这个粒子运动,这其实是一系列动画了,但是由于我这个太卡了,我就不演示了,大家可以自己装一个狐狸,你自己点一下这个播放,OK,我赶紧把它关了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好那么现在如果大家要,刚才演示的是三维的粒子,如果是三维的网格呢,那么大家也可以看一看这个export mesh,这么一个example,好然后今天这两部分就讲完了,我感觉说应该还是比较顺利的。

没有出现像上次那样,在线演示翻车的情况,上一次讲的时候比较疲劳,因为上上周实在是事情太多,讲的时候已经非常疲劳,这周讲的时候精神状态好一点,希望以后精神状态也能像今天这么好,那么接下来如果大家还想学呢。

可以看documentation和之前一样,如果发现bug呢,欢迎给我们提一出,然后也欢迎大家加入我们的开发者团队,我看看有没有什么问题,有同学问了,刚才我们之前提到有一个例子是,a=ti。

static a,我看一下应该是aliasing,在哪儿,对这个地方,这个地方能不能去掉呢,答案是不行的,因为你去掉以后,其实反正就是不符合太极语法。

太极语法要求你必须加一个tidying static,这个大家还是遵守一下,如果你把它去掉以后,它就会编译错误,因为语意就不明确了,物理基础方面有什么推荐的教学,这个其实,暂时来说大家可以看。

课程的推荐阅读材料里面,其实第一部分里面就提到了两个非常好的材料,一个是FDQS写的有限源,然后还有一个是蒋老师写的MPM的理论,蒋老师他们在UCLA的一些,领先的MPM研究者一起写的一个MPM教程。

这个教程写得非常好,大家可以去看,OK,然后,英语不好有点跟不上,这个我得道歉,因为我自己平时说话就这个习惯,我尽量的把我能切换成中文的,我都用中文说了,然后这个slides我觉得。

如果有同学觉得slides上面英文有点多,那我可能也没有什么办法,我只能就这样,因为就这样share了,因为很多词我真的,我自己也不知道它中文是什么,这个可能大家觉得有点奇怪。

但是就是我自己的习惯就是这样的,那么就希望大家能理解一下,这个我自己真的语言水平就是这样,没有办法同时掌握两门语言很熟练,OK,然后,我看看homework1可不可以用SPH制作,当然可以。

SPH的话你可以写一个显示的,Wikicompressible SPH,然后再写一个影视的像DFSPH,或者PCI SPH或者ISPH各种各样的话,大家都可以,都是有很多很多种影视的格式。

大家可以尝试尝试,我觉得还是很有意思的,TI。tip本质上是backpropagation,对exactly就是backpropagation,其实就是你如果做deep learning的话。

其实就是backward path,我说回这个英文的问题,其实主要是还是有很多好的材料是英文的,如果大家掌握这些英文名词以后,可以去看很多英文的材料,这样就相当于学习的是一手资料,如果中文的话。

当然也会有很多人会把英文材料翻译成中文,但是你如果再去看这个中文,就是这个是二手资料,这个中间翻译的时候总会有一些信息损失的,对,如果后面有机会的话,我觉得我应该还是会尽量的写一些中文的教程。

包括如果我真的有时间的话,我可能会尽量的把这个science都翻译成中文,但那个工作量真的很大,我不知道什么时候会真的有机会来做这个事情,暂时我们就先英文,因为毕竟这个课工作量已经非常非常大,OK。

我看看,对,刚才讲到这个variable aliasing的问题,有一个同学问了一个很好的问题,我们做了这个aliasing以后,对新变量的改动会不会影响到旧变量,答案是会的。

你可以认为这个是一个by reference的一个aliasing,我们并不是按value不是按值去拷贝,我们是按reference去拷贝,就像C++里面的这个,那个and符号一样。

那个你加了一个and以后,它就是一个by reference,这个按reference去拷贝,对吧,或者按引用去拷贝,太极法相传播,可不可以直接嵌入PyTorch里面,可以的,这个你可以看。

应该是有一个example。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你打ti。example。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它就会把所有的example全列出来,应该是有,有没有。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里面,这里面好像还没有,OK,这里面好像还没有,这个和grep好像还不是很work,但是你如果看,例子里面。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它是有例子的,我看一下,interacting with external arrays,这个地方你是可以和,这没有PyTorch的例子,我暂时想不起来在哪。

但是你可以用什么tutorch和这个frontorch,然后定一个PyTorch operator,你就可以和PyTorch进行交互,OK,然后,边界条件,边界条件就是非常nasty的一个。

这个叫非常淘气的一个,不是很好处理的一个问题了,然后边界条件我们后面会讲,目前我们写的这个simulation里面,暂时我们的demo里面,暂时还是没有边界条件的,我们只有一些碰撞是这个边界条件,OK。

好,那么我们就这一讲就到这了,然后感谢大家来捧场,下面一讲我们会讲一讲流体,然后大家记得要做作业啊,这个如果只听我讲,不去写代码的话,很容易眼睛看了,眼睛会了手没会,对吧,就像看美食作家王刚做菜一样。

我每次看完他的视频,我都觉得我也能做出来,结果一做往往就做出来,效果就很一般,对吧,所以大家还是要多多实践,多多实践了以后,你很多的掌握就会更加牢固一些,OK,那么今天就到这了,谢谢大家。

大家记得做作业一,然后作业一我们留比较长的时间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大家会应该时间比较充裕的,OK,好,那么各位再见,我们下周再见,拜拜,拜拜,拜拜。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我还以为你会说这些话呢,灭灭火。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值