我在之前一篇文章中提到过,要启动三维结冰程序的研发,这是20年6月份的事情。
结冰程序,有三个关键的技术:流场计算、水滴收集系数计算、冰形计算。而在三维结冰这个方面,一般能完成前两个,就已经达到了相当高的程度,并具备了很强的实用性。
在研发之前,一个非常重要的问题就是要确定,这个软件应该长啥样?这个问题倒不是说界面炫不炫,而是整个软件的设计理念是什么?也就是所谓的概念设计。
基于前面二维结冰程序开发的经验,还有我自己的从业经历,我给这个三维软件一些要求如下:
(1)快。真男人就是要快。好软件就是要快。快就意味着成本低,意味着效率高,意味着设计迭代短。快就是正义。部件级别的完成计算,用时2小时以内,整机级别的计算,控制在4-6小时。
(2)具备可用的精度。工程上能够接受的精度,这个是软件的底线。
(3)程序模块化。大到流场计算模块,小到一个判断单元位置的算法,通通模块化,设置为自定义函数,在主程序里面调用。这样主程序简洁、清晰,子程序可以随时优化更新,不断升级。
(4)设计输入规范。根据软件自身特点,确定输入文件的格式,并具有普适性。就是说,只要按照这个格式和要求提供输入,就能成功计算。
(5)软件输出可直接用于设计。比如像Fensap三维结冰软件,计算完水滴撞击后,如果你想在数模上画出撞击范围,就需要自己后处理,取多个剖面的结果。Spring3D软件则要根据设计研发需求,直接给出可用的结果,避免过多的人工后处理操作。
20年6月份启动的研发,那时我仍在西北,搞飞机试飞,当月就采用三维面元法解决了流场计算问题。进入7月后,一边写参研课题的3万字报告,一边改给科普杂志的1.5万字稿子,一边搞一型飞机的改装与试飞,一边写另一型飞机的重要报告,最后一边,搞三维的水滴收集系数算法(Spring3D-Drop)。
生生忙成了五边人。
8月初,试飞工作告一段落,告别了西北的美食和酒,我返回上海。这个时候,程序已经可以实现三维水滴轨迹的计算,滴收集系数算法进入最难点攻坚阶段。
水滴运动轨迹程序,其中一个门槛就是解决如何判断水滴撞在了翼面上。
物理现象的背后是数学模型。实际上这是个空间几何问题。当前时间的水滴位置和上个时间的水滴位置,连起来是个线段。而翼面已经被我们离散成一个又一个的单元。也就是说,我要判断线段与空间平面的位置关系。
根据空间几何学,他们之间的可能的关系如下:
目前传统的方法就是用空间几何来解决。他们的思路大致是这样的:
(1)根据单元的节点坐标,建立每个单元所在平面特征方程。解方程 1;
(2)根据水滴线段,建立水滴所在直线的特征方程。解方程 2;
(3)求水滴直线与单元平面的交点。解方程 3;
(4)若无交点,则认为是平行。若不平行,判断交点是否在单元内。解方程(or线性代数) 4。
因为你事先不知道水滴会撞在哪个单元上,所有你要循环很多个单元作上述的操作,而且只要水滴在翼面附近,你就得全程监控,实时重复上面的操作,非常耗时。就像日本防空自卫队,被我空军整的疲惫不堪,天天紧急升空,全程伴飞。
这个情况严重违反了我前面提到的设计理念的第一条,必须改变。解决这个问题的关键就是,减少解方程。现在是4次解方程,如果能缩减成一次或者两次,就能大大提高效率。
当时是8月份,我白天忙着应付飞机运营后航空公司反馈的的各种问题。只能在每天坐班车和地铁的路上,在脑子里想反复琢磨怎么少解方程。然后晚上回去尝试。
终于,忽然有一天,我想到一个模型:射箭!
箭击中箭靶,命中点和箭头、箭尾之间,可用建立向量关系。通过引入向量关系,可用把4次解方程的操作缩减为一次。
然而,这个喜悦并未持续太久。我的工作越来越忙,晚上都很难挤出时间做研究。
撞击判断搞定以后,那么每个水滴在流场中的运动轨迹都可以做出来。即便事先有心理准备,但是程序的计算效率之低仍然出乎我的意料。只算一个剖面数十根水滴,就画了两三个小时。这要是整个部件,再考虑到为了计算每个的单元收集系数,需要迭代的数十根水滴,整个部件的收集系数没一个星期时间是算不出来的。
前面的文章中我们提到过,求解每个单元收集系数的关键,是确定单元边界位置对应的水滴初始发射位置。通常来说,水滴迎面过来,撞在机翼上。是不是恰好打在单元的边界,是不确定的,因此需要不停的迭代修正,这个过程需要计算很多水滴。如果我能根据边界位置,反推出水滴初始发射位置,是不是可以不用迭代,一步到位呢?
我当时的设想是,我从翼面单元边界发射水滴,逆着时间线,反推之。就像相控阵雷达那样,每个单元发射信号,接受回波,修正下就可以了。
想的很美,但是现实太丑!逆时间出来的线,和顺时间出来的线,完全对应不上。
时间进入9月份,刚好诺兰的大作《信条》上映。电影展示了正向、逆向时间下,各种反常而有趣的操作。
我一下子又被点燃了激情。劳资也要逆转时间!
在正时间下,水滴轨迹的求解思路是:
(1)已知初始时间点,水滴的位置、速度。
(2)根据控制方程得到水滴加速度,考虑时间推进一定时间后,移动到新的位置,并在气动力、流场速度的共同影响下,更新速度;
(3)重复上述操作,不断推进时间,得到水滴运动完整轨迹。
逆时间最大的问题是,我知晓水滴的在时间T的位置,但并不知晓它的速度,也不知晓它从上个时间点过来的加速度。那我只能假设一个T时间速度。用假设的T时间速度,和T时间的加速度,反向推进时间,更新轨迹。初始速度不准确,每个时间点用的加速度也不准确,最后的轨迹必然不准。
我不死心的尝试在正向、逆向时间之间,建立修正关系。然而这个关系并不具备普适性,反复尝试,可以达到修正部分水滴的效果,但却难以应对更多、更复杂的情形。
逆转时间,失败!
就在这个阶段,我的工作已经忙到无力再做自己的研究了,每天要处理多个完全不搭嘎的事务,大部分都不是技术问题,不要说业余,生活时间都没有了。10月初参加完好基友朋友婚礼后不久,大病一场。晚上中低烧到医院,做完核酸、抽血、CT一套流程以后,变成高烧。确认是细菌感染,又等了很久挂上水,这个是时候我已经烧迷糊了,浑身疼的控不住自己,大口大口地喘气。水是4瓶,我以为两瓶挂完,我应该就退烧了。万万没想到,四瓶挂完,并未好转。
好在,高烧在,智商仍在。我判断我挂的水里面只有消炎药,没有退烧药。然后我开始翻医生开的药,找到退烧药后,两倍量吞下。裹着被子迷迷糊糊睡着了,不多久,浑身被汗湿透,终于舒服了一点。
后面又挂了几天的水,才彻底好转。就在第二天挂水的时候,我意识到,生活要必须要改变,不拿身体开玩笑。然后下载了求职app,准备换工作。
折腾了两个多月,面试了将近20个单位,最终确定下来。这个时候工作交接差不多,我也没啥任务了,又空出时间来。
在写了几个复材程序练手以后,我决定再次向Spring3D发起冲锋。
刚开始我把希望寄托于现有的文献。辗转找到了NASA LEWICE 3D的说明文档,试图找到思路。
看完以后,喜忧参半。忧的是,NASA LEWICE 3D文档里面,并没有说他采用了何种提高效率的做法,一无所获。喜的是,文档里面的配图的画风跟我出图的画风很像,我不相信他们没有遇到过类似的问题。从蛛丝马迹之中,我预感到,他们一定遇到了并且解决了。这坚定了我发展这类插值方法的决心。
仔细思考以后,决定从三个方面入手,提高效率。’
(1)缩短单根水滴的计算时间;
(2)提高水滴的使用率,避免射出百箭仅中一靶的情况。
(3)搞出三维水滴收集系数插值法,用仅可能少的水滴,插值出收集系数。
缩短单根水滴的计算时间
经过调试发现。当前水滴程序里面,最耗时的仍旧是判断是否撞击到翼面的子模块。程序模块化的优势这个时候体现了出来,它还能精准的帮助我们优化程序。
这个时候我刚好去西北出我的最后一次差。再次回到奋战数个月的地方,特别感概,觉今是而昨非。
在西北的那几天,我前后探索了两种思路都取决了不错的效果。一种是开发一个专门的精确识别是否需要启动撞击判断程序的算法,减少撞击判断。另一种是,开发一个精确识别哪些单元需要被判断的算法,减少撞击判断中的循环单元数量。
这两个方法用上以后,效果是立竿见影的。原先数个小时的工作,现在只要四到五分钟就能算完。
提高水滴的使用率
提高水滴的使用率的目的,前面也提了,就是要做神枪手。争取一个水滴消灭一个单元,而不是像下图这样。我在原先程序基础上也做了两个方案,一个是水滴非均匀发射,一个是保持总数不变,嵌套迭代。也都取得了很好的效果。
基本上,通过有限个水滴,就能把撞击范围精确定位出来。
三维水滴收集系数插值法
这个是我最得意的一招,无论是原创性还是精妙程度,都值得吹嘘很久。之前搞二维的时候,我就搞过一个插值。而三维的插值,对于物理现象的把握、思路和程序设计水平提出了难度高出几个量级的要求。
限于核心技术不外泄的原则,这里只讲下插值方法需要解决的难点:
(1)每个单元边界对应的水滴发射位置的插值定位技术;
(2)有限个水滴,如何精确定位撞击边界线;
(3)从剖面到展向,二维、三维尺度上结果的精确性保证。
我先解决了剖面收集系数曲线,然后又解决了三维尺度上单元交界的处理,这个时候,应该是可以一次算出水滴收集系数的三维云图了。但是近乡情更怯,我先计算多剖面的云图,确定没有问题了,才最终点下终极计算的按钮。
终于,在离职前一天的晚上,心心念念的水滴收集系数云图,在不到20分钟的时间,出来了。
云图结果和预期一致。这个图,我在脑子里期待了半年,它是我不断克服困难,加班加点的动力所在。怎么形容这种成就感都不过分。
云图拿到的第二天,我彻底离开了单位。毕业前就开始做结冰算法,学结构强度的我,从零开始进入这个领域,而后参加工作,至今三载。无数个日夜的思考,无数个日夜的探索,无数次的失败,无数次的喜悦。
一段征程在这里画上句号,或许正当其时。
最后,更多精彩内容,欢迎大家关注“320科技工作室”微信公众号。