大型通用仿真软件是一种综合性的信息产品,融合了软件工程、计算数学、工程学、物理学、以及产品设计等多学科内容,开发难度大、研发周期长。一款成功的通用仿真软件,与良好的设计定位和构架开发密不可分。随着科技的发展,我们发现现代仿真软件和10年前的产品已经有了很大的不同。计算结果的精确性与稳定性,友好的人机交互界面,已经不再是开发者的重心,因为这些需求已经极大的解决了。由于AR/VR、云计算、人工智能等新技术的出现,对通用仿真软件的灵活性提出了新的要求。需要产品不仅可以本地桌面运行,还可以云端服务器部署;可以本地求解计算,也可以连接远程的高性能计算集群计算,对各种求解器的调用需要更快捷灵活,甚至达到所操作即所得的实时仿真。这些要求,对开发现代大型通用仿真软件带来了新的挑战。本文从产品的角度,探讨现代大型通用仿真软件的设计与构架。
任何软件的设计都是为了满足产品的定位与客户的需求。设计需要小而美,产品如果设计的过分庞大,会造成开发不堪重负,从而导致产品迟迟无法交付。而通用大型软件本身就是应用面很大的产品,则更需要将设计最小化。设计的关键要有预见性,对于仿真软件这种周期性较长的产品,设计需要有提前5-10年的远见。本文从产品与用户的角度,提出了现代大型通用仿真软件应当具有功能:
不同进程之间灵活的调用、通信、与数据传输机制。支持实时计算与渲染功能。支持调用多个不同的求解器,网格划分器等计算密集型可执行程序。
提供简单直接的外部调用、启动、关闭、交互的接口。使得自动化回归测试易于实现和维护。
友好的图形化交互界面。支持虚拟现实与增强现实,显示设备不仅仅限于桌面显示器。
支持云计算,支持远程调用,远程可视化,团队协作功能。
支持用于人工智能自动化分析或求解的数据提供接口。
支持多物理场与多尺度分析的弱耦合接口与设置。
软件构架是连接设计与开发的重要环节。对构架师有比较高的要求。大型通用仿真软件由于其涉及面广,细节多,往往需要对仿真软件开发有多年经验的团队,经过一系列的论证得出。当前大型通用软件的构架并没有固定格式,基本是由一些大型厂商自主研发。一个通用的构架格式,对于整个行业的发展都有益处。WELSIM对大型通用仿真开发有多年的实际经验。按照以上的设计要求,提出了一套切实可行的方案,其中一部分已经实际应用到产品开发之中。需要明确的是,软件构架的核心目标是最小化维护成本,而并不是实现功能。
下面,就来探讨现代通用仿真软件构架中需要考虑的核心问题,其中部分功能已经在WELSIM中实现。
进程与消息传递机制
现代仿真软件对灵活性提出了很高的要求,设计1也明确的提出了需求。大型软件不可避免的需要对多个可执行程序进行管理与调度,同时进程之间的通信也极为必要。然而,多进程管理业界并没有一个通用的标准,需要根据产品的功能与需求实现定制构架与开发。WELSIM设计了一种基于WebSocket接口与RPC接口的进程管理与消息传递机制。WebSocket接口用于GUI主程序与Daemon程序之间的通讯。RPC接口用于求解器等子程序与Daemon的通信。RPC通信采用JSON数据格式,对于大数据,可以通过直接读写内存,或二进制文件的形式实现。
如上图所示,当主程序(GUI程序)启动以后,会同时启动一些必要的子进程。其中daemon.exe是所有子进程的控制节点,起到连接主程序与其他程序(如求解器)的控制器作用,支持WebSocket通信。start_solvers.exe是求解器的控制进程,支持RPC通信,考虑到通用仿真软件的求解器可能有多个,所以支持动态添加子进程。start_node.exe是本机在网络中的控制信息,可以发现同伴与被同伴发现,用于协同工作的共享与控制。start_mesher.exe作用和start_solvers.exe类似,用于网格划分器的控制。start_data_layer.exe控制本机的数据层,用于共享本机的计算数据。
本构架涉及了两种通信机制,WebSocket是一种在单个TCP连接上进行全双工通讯的协议。服务端和客户端可以建立永久连接,并进行双向数据传输。RPC是一种通过网络请求服务,但不需要了解底层网络技术的协议。它既可以用于网络,也可以用于本机的多进程服务通信。RPC的端口通过配置文件实现,在使用默认端口设置同时,允许用户修改端口。RPC的端口不对因特网开放。使用TLS证书用于保证通信的安全。下面结合本文的构架设计,详细讨论两种接口在通用仿真软件上的实现。
WebSocket API服务
当主应用程序runWelSim.exe启动后,同时启动Deamon服务。Deamon作为服务端,runWelSim.exe作为客户端,建立永久的基于JSON格式的双向通信。作为服务端Deamon接受前端发送的请求,如网格划分,求解计算,云计算,远程分享等。经过处理后,调度使用各种子进程,完成任务。得益于双向通信,Deamon将任务完成进度实时返回给前端。如在实时仿真的应用中,Deamon通知对应求解器进行求解计算,并将每一步的求解结果返回给前端,前端主程序在收到计算结果后,更新相关显示,如实时渲染结果云图等。
Deamon使用WebSocket的另一个好处是,前端主程序既可以是桌面应用程序,也可以是网页应用程序。对前端的开发框架与编程语言没有任何要求。产品在桌面平台使用多年后,可以用最少的工作量移植到云端平台。值得一提的是,WebSocket在实际开发中,有大量的异步调用,开发者需要了解相关的网络服务技术。
RPC API服务
RPC是一种基于请求/响应(Request/Response)的远程过程通信机制,传输效率高,支持本地与异地调用。因此作为大型仿真软件子程序的首选。从编程的角度,这里的RPC API是一种请求/响应风格的异步函数。Deamon所属的所有子进程,如solvers, nodes等,都会提供RPC服务,接受客户端的实时调用。如下图所示,Deamon可以对所属的子进程进行访问,同时子进程及时返回给Deamon客户端JSON格式的数据内容,这些数据包含一个调用成功与否的标签。
从安全性角度考虑,并不是所有的RPC的端口都应该公开暴露,比如Nodes和DataLayer进程的端口是应该私密的。而求解器端口则可以公开暴露,方便客户端快速调用。RPC命令设计主要是get/set等函数,同时每个命令含有帮助提示,其他开发者或者使用可以通过-h标签,快速了解调用RPC的方式,以及返回内容。RPC的访问可以通过不同的语言实现,如Python,C++,或Javascript等。开发上有很多开源包可以使用如gRPC、OpenRPC等。
用户交互界面的GUI设计与构架
图形交互界面是大型通用仿真软件研发中的关键技术之一。它需要考虑到各种物理类型的仿真需求,要易于维护和增加功能,同时能够提供直观、易用、功能丰富的界面,使用户能够方便快速地进行模型构建、仿真设置、结果查看等操作。是一个复杂且长期的研发过程。WELSIM经过多年的和迭代,已经完善了前端GUI模块。现将软件人机交互的总体设计展现如下。
1. 菜单栏,用于展现所有可用命令。
2. 工具栏,用于展现常用命令。根据产品需要,可以使用传统的单个按钮。当命令较多时,可以使用流行的Ribbon布局方式。
3. 项目树窗口,用户可以方便快捷地添加、编辑、复 制、或者删除节点,实现动态控制仿真分析中所需要的元素。窗口中的右键弹出菜单起着重要作用,用于实现以上功能。节点状态机制,用于在节点图标右下角显示当前节点的状态,如成功,错误,未定义等。
4. 属性窗口,属性窗口是项目树的有力补充,常放置于项目树窗口下方。承担了仿真数据输入的主要功能。属性窗口动态显示当前节点的数据内容。显示数据的同时,允许用户输入或者修改数据。
5. 三维视图窗口,三维图形窗口占据了屏幕的主要空间,是仿真软件的主要模块。因此可以布局的元素非常多,这也导致了设计与开发上的困难。三维窗口有大量的鼠标与键盘交互操作,都需要精心的设计与开发。鼠标的交互设计需要符合用户使用习惯,同时有创新且更加好用。
6. 输出窗口,输出由系统产生各种文本信息,常放置在屏幕下方。输出窗口最重要的功能是提示各种错误与警告信息,同时向导用户解决问题。
7. 控制台窗口,和输出窗口类似,现代仿真软件还会支持控制台命令窗口,如Python等解释性语言的输入控制。可以满足部分用户的二次开发需求。同时为自动化测试系统提供了接口。
8. 表格窗口, 表格窗口主要用于显示数据,有时也提供修改数据的功能。作为通用仿真软件,表格需要支持各种类型的数据与单位,如边界条件数据,结果数据,材料测试数据,曲线拟合数据等等。需要支持修改单位,数据排序,数据导入导出等功能。
9. 曲线窗口,曲线窗口用于显示二维曲线,与表格窗口共享数据。通常放置于表格窗口下方。通过图形和曲线将表格数据直观地显示出来,是提升用户体验的重要窗口。曲线窗口还可以含有动画显示控制器,用于仿真后处理中常用的动画显示与视频生成。
10. 额外主窗口,对于一些复杂的数据输入与显示,需要额外的主窗口来显示。如各种材料的数据编辑,大型表格的输入显示等。可以通过新建标签的方式与三维显示窗口平行显示。
11. 各种弹窗,根据命令的类型与重要性,向用户展现弹窗窗口。总体的原则是,尽量少用弹窗。
关于大型通用软件的GUI详细介绍可以参见《仿真软件中的弹出菜单设计与开发》《大型通用仿真软件的窗口设计与开发》二文。
尽管桌面GUI在通用仿真领域有很大的优势,能满足几乎绝大多数的使用需求。软件设计与构架是需要有预见性的,GUI设计开发也一样,在考虑到将来原生基于云端的网页GUI时,可以使用基于Javascript语言的前端框架,如Electron等来实现开发。在保证桌面用户界面的同时,可以够快速的开发出基于云端的网页GUI。
自动化回归测试系统
大型通用软件的自动化回归测试系统是很有必要的。尤其对于工程仿真软件,在保证软件稳定性的同时,还需要数值计算正确,误差在可控范围内。需要有一套良好的自动化回归测试系统。通常自动化测试的金字塔层级划分如下,有单元测试,整合测试,全局UI测试。单元测试用于实现微小算法,如WELSIM中含有的大量单位转化的单元测试以保证准确性。整合测试用于测试如Deamon等可执行程序,如通过WebSocket输入要求进行某种计算并验证结果。前端UI测试名义上测试交互界面,其实也测试数值结果。这三种测试的时长也随着复杂性而递增。对于大型产品,最理想的测试方式就是从用户使用角度进行端到端测试,因此贴近GUI操作的测试系统是效率最高的。对于产品整体的质量控制最为有效。
因此对于大型现代仿真软件,建立UI自动化测试系统是必不可少的工作。实现起来,主要是通过与GUI的框架系统建立关联,这种关联以观察者模式为主,可以是事件,Callback,或Signal/Slot等方法。WELSIM提出的自动化运维系统,含有一个中间件,用于给前端界面提供命令,以及读取UI的状态。同时含有一个客户端,用于测试人员使用。如下图所示,中间件主要分为两大模块,转换者(Translator )和操作者(Player),用于实现对GUI的控制与读取。
自动化运维系统的客户端,相当于重新开发了另外一套软件,在通过中间件对WELSIM的UI进行控制以外,还需维护整套测试文件与历史数据。自动化测试的客户端应该实现以下功能:
允许添加,修改,删除各种测试案例。
测试报告生成系统,便于查找,与追踪。
全自动化运行,无需人工干预。
验证属性值,处理程序崩溃,无限循环,图像像素对比等。
测试文件仅需要小程序文本。无需其他依赖库或依赖程序。
目前,WELSIM的自动化测试框架也在不断完善之中,将来有可能会开源自主研发的自动化测试框架与各种验证算例,贡献开源与仿真社区。
云计算与网络支持
现代通用仿真软件需要对网络支持有着更好的可拓展性。得益于多进程设计和RPC服务,本文的框架可以很好的满足云计算,以及各种复杂网络的支持与拓展。其中Nodes进程管理与其他机器的网络连接与通信,DataLayer进程用于管理,存储,与发布数据。其自带的RPC服务可以快速的支持各种网络应用。同时应用TLS证书等加密方式,提高网络应用的安全性。对于大型数据,DataLayer会进行相应的压缩与解压缩,提高网络传输效率。
其他
由于篇幅有限,本文还有很多内容无法详细描述。如:
CAD几何引擎。
网格划分器,求解器。及其高性能实现。计算密集型进程调用与通信。
后处理显示开发,VR/AR实现。
数据持久化。
二次开发功能,脚本控制功能,插件应用的集成与开发。
全球化与本地化,多语言支持。
结果显示,报告生成系统。
多物理场耦合。
多尺度场耦合。
优化工具耦合,不确定性量化工具的耦合。
以上内容,争取在以后的文章中,专门讨论。
总结
大型软件的构架是一项复杂的工作,通用仿真软件由于涉及各种数值方法与应用场景,则显得更为复杂。既需要覆盖各种计算,又能与时俱进,体现出现代软件的灵活性,如实时仿真,云计算、人工智能,VR/AR、3D打印等新技术。对于产品经理与构架师提出了很多挑战。本文提出的基于RPC的现代仿真软件构架,可以满足以上要求,为产品的长期维护打下良好基础。
对于大型软件的构架,应该跟随产品的定位以及主要用户的需求。对于影响产品统一性的设计需要舍弃。舍弃不必要的功能是现代大型通用仿真软件设计的核心。本文提出的构架思路也可以应用于其他的现代大型软件。