风雷(PHengLEI)通用CFD软件设计*

2020-03-04 08:20何先耀
计算机工程与科学 2020年2期
关键词:数据结构编程框架

赵 钟,何 磊,何先耀

(中国空气动力研究与发展中心计算空气动力研究所,四川 绵阳 621000)

1 引言

针对航空航天、地面交通、能源动力等领域对空气动力数值模拟的需求,为了开发通用的计算流体力学CFD(Computational Fluid Dynamics)软件,面向相关领域提供高效、高可信度的数值模拟手段,以及多学科、精细化的设计工具,我国启动了国家数值风洞NNW(National Numerical Wind tunnel)工程,以建设拥有自主知识产权、开放共享、达到世界一流水平的空气动力数值模拟平台。风雷(PHengLEI)软件,是NNW工程的通用CFD软件,是工程的重要组成部分,将对标国内外主要CFD软件。

经过几十年的发展,国内外已经有多个知名的CFD数值模拟代码。OpenFOAM[1]是一款基于非结构网格的开源代码和框架,以C++语言面向对象思想设计,具有良好的可扩展性,有丰富的算法库。源于libMesh的Moose[2,3]是一个有限元方法开源类库,主要面向固体力学、弹性力学、热传导、高精度模拟等问题。Overture[4]是一套结构网格框架,开发了包括网格生成、有限差分、边界条件、数据存取等数值计算方法。SU2[5]是由斯坦福大学发布的开源非结构CFD代码,按照面向对象的思想开发,除常规CFD计算外,还有网格自适应、气动优化等面向多学科数值模拟的模块,近年来在全球得到了广泛的应用。JASMIN/JAUMIN/JCOGIN[6 - 8]是分别面向结构网格、非结构网格、无网格数值模拟的编程框架,为惯性约束聚变、武器物理、电磁模拟、粒子输运等多个领域的软件开发提供了底层编程开发库。

CFD是一门同时涉及计算数学、流体力学和计算机科学的交叉学科,数值模拟的最终实现要依靠可执行的软件。长期以来,CFD软件的开发者基本上是流体力学、计算数学专业人员,正因如此,与常规的应用软件相比,CFD软件有其鲜明的特点:属于科学计算类软件,密集计算,频繁访存(尤其是非结构算法),软件执行过程人工交互少,功能单一,任务和用户群明确,大多是面向过程开发的,缺乏软件工程思想,规模一般较小。这些软件在多年的研究和应用中发挥了重要作用,但是随着CFD应用的拓展,工程应用的需求也逐渐从单一功能向多学科耦合模拟、从小规模到大规模并行计算的转变,尤其是当前高性能计算HPC(High Performance Computing)硬件正处于从P级(PFLOPS,运算速度每秒千万亿次)计算到E级(EFLOPS,运算速度每秒百亿亿次)计算的过渡期,以前众多小而精的软件逐渐显现出劣势。对此,近十年来,国外多个CFD软件也在不断更新换代,并制定了长期的下一代CFD软件研发计划,主要趋势是增强软件工程化,强调结构/非结构求解器、二阶精度/高精度、不同学科的耦合计算能力,具备面向下一代E级计算机大规模并行计算的能力。整体看,CFD软件的发展趋势是集成多个学科物理模型求解器,构建大型软件平台。

在欧洲,由德宇航实施的Digital-X项目[9],旨在研发1个具备高度适应性的大规模并行多学科分析优化设计平台,该软件系统集成了包括CFD流动模拟、结构动力学模拟、六自由度运动模拟、不确定度量化分析、旋翼模拟、自动化工作链、多学科优化等7大领域的软件包,德宇航的9个研究所和空客公司、相关大学参与研制。Flucs(Flexible Unstructured CFD Software)[10],是由德宇航正在研发的一款新一代CFD软件,目的是为Digital-X项目中的多学科数值模拟提供基本的CFD流动求解器。该软件的算法模块来源于非结构求解代码TAU[11],由于TAU在适应下一代HPC系统、多学科模拟、高精度求解的需求上越来越困难,德宇航在借鉴了TAU的大量算法基础上,着手开发全新的下一代CFD软件Flucs。与德宇航的传统CFD软件相比,Flucs最大的变化体现在软件开发模式、编程框架(Framework)、并行计算等几方面。在编程框架方面,摒弃了传统的面向过程的开发方法,采用C++语言面向对象的思想建立1个模块化的编程框架,将空间/时间离散方法、并行、数据结构等具体的底层算法抽象为模块,形成编程框架,在此框架上,集成开发出了二阶精度的有限体积求解器、DG(Discontinuous Galerkin)高精度求解器。Flucs的并行框架采用了3层并行模式,以适应下一代的HPC系统。

在美国,自2007年始,美国国防部高性能计算现代化计划DoD HPCMP(Department of Defense High Performance Computing Modernization Program)开始实施总投资达3.6亿美元、持续12年的CREATE(Computational Research and Engineering for Acquisition Tools and Environments)项目[12],旨在研发新一代关于舰船(Ship)、飞行器AV(Air Vehicle)和射频雷达RF(Radio Frequency)等设计和分析软件系统,以及独立的几何建模和网格生成模块MG(Meshing and Geometry)。其中的Kestrel[13]是为CREATE项目的飞行器(AV)子项提供飞行流动模拟分析的软件。Kestrel作为1个大型CFD模拟系统,遵循2大设计原则:(1)具备线性扩展性的万核量级并行计算能力;(2)通过代码重写或模块分解的方式集成已有的传统软件。前者强调对未来HPC的适应能力,而后者主要是强调软件的开发设计模式,即模块化。模块化设计主要有几个特点:(1)模块化集成。Kestrel中包含1个通用可扩展框架CSI(Common Scalable Infrastructure),主要起到集成各功能模块和数据总线的作用,即各功能模块通过CSI集成,通过与CSI的接口传输数据,从而实现各模块间的数据共享。(2)中粒度集成。各模块间的集成既不是像Flucs一样在源代码层次细粒度集成,也不是在可执行程序层次的粗粒度集成,而是在中粒度集成,即各模块分别编译后在链接阶段集成。这种集成方式的好处是,各功能模块可以采用Python、C/C++、Fortran等不同的编程语言分别编译为不同的组件,具备高度灵活性。(3)包含SDK(Software Developer Kit)和Plug-ins 2大集成模式,分别适用于团队内部和外部的模块开发集成,二者的区别是前者代码共享,后者只是组件共享。

总之,不管是美国的CREATE项目,还是欧洲的Digital-X项目,在关于飞行器空气动力学研究方面,都致力于在现有发展数十年的In-House CFD代码基础上,开发新一代大型CFD软件,并强调学科融合、求解算法融合、网格类型融合。

国家数值风洞NNW是以建设大型CFD软件系统为目的的重大工程,PHengLEI软件是NNW数值模拟软件系统的通用CFD软件,将在此前已全国发布的版本的基础上,集成中国空气动力研究与发展中心和国内相关优势单位,在直升机旋翼、飞机结冰、风工程、化学反应与燃烧、虚拟飞行、结构/非结构高精度等十多个领域发展的CFD研究与软件成果,打造面向航空航天、地面交通、能源环境等领域绝大部分空气动力学模拟需求的大型通用CFD软件。文献[14,15]已介绍了PHengLEI软件原型系统(HyperFLOW)的体系结构和数据结构。为了满足NNW多物理模型求解器继承开发的需要,经过多轮敏捷迭代,PHengLEI已重构为面向多学科、大规模并行的新一代大型CFD软件框架,本文将介绍最新的软件设计思想,包括体系结构设计和数据结构设计。

2 设计原则

国家数值风洞的数值模拟系统面向多种物理问题求解,将集成开发多个求解器。软件框架是大型CFD软件的“骨骼”,如果设计不合理,可能导致软件扩展性不足,架构随着软件的扩展变得越来越紊乱,最终可能导致颠覆性重构。因此,在软件开发之初就应该设计合理的、易扩展的软件框架。大型CFD软件设计应着重考虑几方面特性:

(1)多学科耦合模拟应用的灵活性和可扩展性。真实流动往往是多学科耦合问题,如多相流动、气动弹性、气动声学、气动/电磁、气动/结构/运动学等,都是典型的多学科耦合问题。大型CFD软件架构的灵活性体现在:除了满足N-S(Navier-Stokes)方程求解外,还要兼顾其他学科控制方程耦合求解的需求;可扩展性体现为:耦合求解时,必须保证能耦合并行计算,并具有良好的并行性。

(2)具备适合团队开发的、构件化的高可复用性。NNW工程的CFD软件功能复杂,参研人员多,对于数据结构、并行模式、几何网格等底层数据,和网格转换、并行分区、壁面距离计算、数学算法等工具,应构件化、模块化,通过高内聚、低耦合提高复用性,以尽可能提高软件精益化水平。

(3)大规模并行计算的可扩展性。受功耗的限制,以后的高性能计算机势必越来越“绿色”,只能以提高计算核数的方式来提高计算性能,因此CFD软件框架必须具备高并行可扩展性。

在满足上述原则的前提下,综合考虑当前软件技术的发展现状,采用C++语言,以面向对象的思想,设计开发了软件框架。核心思想是数据抽象、继承和绑定。通过数据抽象使接口和实现分离,达到构件化、模块化、高内聚、低耦合的设计目的;通过继承和绑定,实现忽略特化各种对象的统一调用。

3 体系结构设计

3.1 整体组成

CFD软件体系结构定义了在给定环境下,数据结构、网格几何、数值算法、并行模式等要素间的层次、约束、调用与逻辑关系的设计决策。图1是风雷软件整体组成情况,从底层到顶层主要包括:

(1)数据结构与并行支撑层,定义了网格几何、流程、参数的数据结构,支持基于COI(Coprocessor Offload Infrastructure)/SCIF(Symmetric Communications InterFace) 数据传输的MPI/OpenMP混合并行的数据通信机制。

(2)编程框架API(Application Programming Interface),将CFD软件中所用的数值算法(如空间离散格式、梯度算法、限制器等)、数据结构、边界条件、并行通信接口、工具类(Toolkit)等,抽象封装为高内聚的类库,这些类高度独立、模块化,开发者通过调用对象的公有接口,快速形成不同学科的求解器Solver。

(3)求解器(Solver)。包含流体求解的N-S方程求解器、湍流求解器以及其他学科物理模型求解器。这些求解器均为Solver基类的派生。

(4)网格(Mesh)。包含与CFD求解相关的网格操作,如六自由度运动与网格变形、网格自适应、重叠网格装配等。

(5)可视化(View)。包含后置可视化相关操作,如输出到各类可视化软件接口、虚拟可视化(VR)、并行可视化等。

(6)三方库(3rdparty)。可集成第三方库,如CGNS(CFD General Notation System)标准库、网格分区Metis/ParMetis库、分别基于同构/异构架构优化的数学库等。

(7)文档。包括开发手册、理论手册、用户手册、开发环境使用说明等技术手册。

(8)知识库(Tutorials)。集成对编程框架API中常用类模块和工具的调用实例,既可作为单元测试,也可作为二次开发指导用例。

(9)界面系统。提供基于本地计算的GUI(Graphical User Interface)界面、适用于远程集群(如超算中心)的Web界面云平台。

编程框架、并行计算、求解器和网格是CFD软件的核心,下文将重点介绍。

Figure 1 Composites of PHengLEI图1 风雷软件组成

3.2 面向CFD开发的编程框架

在空气动力数值模拟系统中,由于涉及到多学科、多物理模型方程的求解,整个系统将由若干个求解器(Solver)构成。这些求解器之间在很大程度上有大量的共用部件、基础部件,例如网格几何前置处理、并行计算、计算结果后处理、通量格式、限制器、隐式计算方法、湍流模型、转捩模型等。如果每个求解器都单独开发,不仅重复性功能多、效率低下、接口混乱,而且没有统一规范标准,不易于维护,难以统一集成于一个平台上。

因此,有必要将不同的求解器之间的最大的共性部分提取出来,将这些共性部分以编程框架的形式固化,以类库的形式为其他求解器提供“公共基础”。CFD编程框架是模板化的代码,可以帮助完成许多基础和细节工作,其他开发者只需将精力投入到系统的逻辑设计和特定算法的研发之中,而不必再考虑底层,可以大大提高开发效率。同时,使用统一的框架,使得整个软件体系具有良好的结构和扩展性。编程框架也可以不断升级,在不影响上层应用的情况下提高性能(如异构并行算法的改进),系统中所有的CFD应用都可以同时得到框架升级带来的好处。

当前,在科学计算领域,有多个国内外知名的软件框架,但在计算空气动力学领域还没有比较成熟的专门编程框架。在OpenFOAM、Moose等编程框架中,一般将微分导数项抽象为与数学公式类似的形式(如“fvm::ddt”“fvm::div”分别代表对时间微分算子、散度算子),这种模式有2个问题:(1)复杂物理方程在隐式处理时难以线化,工程应用能力弱;(2)与计算空气动力学领域中常用的“通量”形式的使用习惯不符合。在目前国内尚无专门面向空气动力模拟的CFD软件框架的情况下,迫切需结合计算空气动力学学科特点,设计能同时满足任意网格类型的超大规模通用CFD软件编程框架。

对于提供二次开发接口的软件框架库来说,采用分层结构是一种较好的选择,有2个优点:(1)通过对体系结构分层封装,用户仅通过顶层的API接口,就能完成CFD的软件开发,从而将用户不关心的底层数据封装,如并行、网格;(2)将整个框架分层后,各层之间仅通过定义好的接口交换数据,因此各层内部的模块可以任意重构,而不会影响到全局,有利于采用敏捷实践的方法升级软件框架。图2是设计的CFD编程框架PHengLEI-API的层次结构,主要包括:

(1)内核底层。控制参数、数据结构、第三方库、并行通信等基础模块被抽象为类库,供上层调用。该层模块可根据计算机硬件特点优化、适配,从而使开发者与硬件隔离。如在设计的并行框架中,将同构/异构通信隔离至底层,开发者调用接口完全一样。

(2)数值算法层。主要抽象计算流体力学中常用的数值算法,如通量格式、限制器、梯度、边界条件、文件IO等模块;还为开发者提供工具类,如日志工具、时间统计等。

(3)功能层。主要是将上层的模块抽象为API接口。

(4)应用层。按照给定的多重网格控制流(下文介绍),集成编程框架模块开发求解器。

Figure 2 Hierarchical structure of programming framework PHengLEI-API图2 编程框架PHengLEI-API 模块及分层结构

CFD开发者调用编程框架开发求解器的主要过程包括:

(1)引用PHengLEI编程框架API头文件“PHengLEI.h”,执行初始化操作。

(2)创建网格几何类,指定网格文件名并读入网格。

(3)设置计算所需的参数,如方程模型、通量格式、求解器等。

(4)各进程根据给定的参数创建求解器,并加载到网格块上。

(5)迭代求解方程。

(6)求解结束,调用退出接口。

3.3 几何计算域(Zone)与求解器(Solver)

在并行计算、多学科模拟计算过程中,全局计算域通常被分解到不同的计算区域进行,例如计算域被划分为子域后,被分配到不同的进程、执行不同的物理过程模拟。PHengLEI中,将几何计算域(Zone)与求解器(Solver)作为数值模拟的基础。

整个CFD计算域(Flow Field)分为2层(如图3所示):第1层是Region分区;第2层是Zone分区。整个计算域被分为多个Region,每个Region被进一步分为多个Zone子分区。Region/Zone 2层分区分别对应1级分区和2级分区,通过递归并行分区方法得到[16]。图3是圆柱绕流算例(图中曲线是流线),整个圆柱计算域被分为上下2个Region分区,每个Region分区被分为3个Zone子分区。Zone是框架的核心,负责存储网格、加载求解器、存储流场变量和参数数据库。

Figure 3 Geometric computational field of Region/Zone图3 几何计算域Region/Zone

图4是计算区域Zone分区、网格与求解器间的关系。Zone中存储直接用于CFD计算的网格Grid,Grid既可以是结构网格也可以是非结构网格,含有点坐标、单元-点、单元-面、邻居连接等信息。根据计算任务,在每个Zone上分别加载求解器Solver,每个Zone上的Solver可以相同也可以不同,如对于结构/非结构混合计算而言,可以在不同的Zone上加载结构或非结构求解器。4.1节中的不同类型的数据结构也存储于Zone上。

Figure 4 Relationship among zone, grid and solver图4 计算区域、网格与求解器间的关系

CFD不同求解器间既有差异又有共性,将共性提取出来抽象为求解器基类,从基类派生出具有差异化的其他求解器子类。基类Solver存储了求解器的共性成员和接口,如Solver编号、标识、初始化等;由基类Solver派生出CFD求解器类(CFDSolver),其中定义了CFD求解器的共性成员和接口,如计算网格、空间离散、时间推进、边界条件处理等纯虚函数接口。CFD中的求解器主要包括N-S方程求解器、湍流方程求解器、DG(Discontinuous Galerkin)求解器、MHD (Magneto Hydro Dynamics)求解器等,这些求解器既有共同点,又有不同点,在基类CFDSolver中已经定义了共有成员和功能,由此派生出对应的子类:N-S方程求解器类、湍流方程求解器类、DG求解器类、MHD求解器类等。上述不同的求解器可以基于结构/非结构/混合网格求解,因此不同的求解器又可以派生出基于不同网格的求解器类。例如,由N-S方程求解器派生出基于结构网格解算的N-S方程求解器(NSSolverStruct)和基于非结构网格解算的N-S方程求解器(NSSolverUnstruct)。图5是求解器的继承关系图。一些非典型CFD求解器,例如DSMC求解器、Boltzmann求解器,可直接从Solver基类派生。

Figure 5 Inheritance relationship of solvers图5 求解器(Solver)继承关系

按照图4定义的方式,将不同的求解器子类加载到计算区域Zone上,实际计算过程中调用Solver/CFDSolver对象的虚函数,动态绑定到真实求解器接口,通过多态性满足多学科耦合计算需求。

3.4 结构/非结构耦合计算方法设计

网格类型无关性是大型CFD软件框架设计的出发点之一,因此PHengLEI框架既能同时适应于结构网格、非结构网格,还能实现结构/非结构网格下的求解器耦合计算。结构/非结构2种求解器可独立运行:当使用结构网格时调用结构求解器,使用非结构网格时调用非结构求解器。也能进行结构、非结构求解器的同步耦合计算:当计算域中同时有结构、非结构网格时,分别在其上运行结构、非结构求解器。

结构/非结构耦合计算的关键技术是2种网格类型交界面的数据通信。在2种网格内部分别调用结构/非结构求解器计算,2种网格间的交界面形成各自求解器的边界条件,将这种边界条件抽象为InterFace(交界面)类。在结构网格和非结构网格之间,通过交界面建立一一对应的面映射关系,计算模板相应扩展:对于结构求解器(如图6a所示),在内场单元i处将另一侧的非结构网格体心值视为其虚拟单元(i+1);对于非结构求解器(如图6b所示),在内场单元le处将另一侧的结构网格体心值视为其虚拟单元(re)。对于结构求解器,往往需要在边界处拓宽虚拟单元模板,除了i+1点外,还需要i+2,…,i+n点信息,此时可将与非结构网格相邻的若干层结构网格视为非结构网格,建立所需要的虚拟点信息。

结构/非结构网格交界面InterFace的信息交换方式与并行信息交换方式相同(3.6节)。

Figure 6 Stencil of structured/unstructured coupled solver图6 结构/非结构混合求解器模板

3.5 基于多重网格MG(Multi-Grid)的流程控制

面向工程应用的大型CFD软件需考虑加速收敛技术,多重网格技术是其中一种成熟的方法。CFD软件的核心是各类求解器,本文设计了一种适用于任意求解器的并行多重网格控制流程(如图7所示):程序启动后,先读入网格、控制参数等输入信息,然后根据计算任务,将对应的各类求解器加载到计算区域Zone, 利用“迭代控制器”Controller依次初始化每个Zone上的所有求解器,并进入多重网格V/W循环迭代求解流程。这里,“迭代控制器”被设计为一种统一管理Zone/Solver的代理,例如,在Zone_i上加载了N-S求解器、SA(Spalart-Allmaras)求解器,一个迭代步内,先进行N-S方程求解,此时绑定Zone_i/NS求解器并计算,完成后,绑定Zone_i/SA求解器并计算。

Figure 7 Control workflow of multi-grid图7 多重网格控制流程

求解器开始迭代计算后,在每次迭代内部,通过迭代控制器控制多重网格流程,多重网格循环中的每个接口在Solver基类中被抽象为纯虚函数,由于每个具体的物理模型求解器都继承自Solver基类,因此这些求解器子类都受迭代控制器管理,并进入统一的多重网格循环,在具体执行插值算子、限制算子、迭代松弛(Relaxation)等数值算法时,通过动态绑定执行真正求解器的接口。

3.6 并行计算框架

国内外已经有不少并行计算框架,如OpenFOAM、Moose、JASMIN/JAUMIN/JCOGIN,这些框架都是单独针对结构网格或者非结构网格开发的,难以做到并行通信对网格类型的无关性。目前在CFD工程应用中,结构网格和非结构网格在不同应用领域都有各自的优势。如果对于结构、非结构网格分别采用不同的并行计算框架,那么同样的一套计算方法将难以适应不同的网格类型,且维护成本高。面向工业应用的CFD软件是作为气动数据生产的“数值风洞”,软件的工程实用性、团队开发能力是必须满足的基本要求,要求代码将并行隔离至底层,同时保持代码的可扩展性、稳定性,以及对各种网格类型的适应性。

PHengLEI并行框架详细介绍见文献[16],这里只简述。设计原则是:(1)将并行数据交换隔离至底层,不管是同构并行还是异构并行,CFD领域专家编程与并行无关;(2)在同一个框架上,兼容结构/非结构任意网格类型CFD并行计算。

为满足第1条原则,PHengLEI将物理模型求解器开发与并行计算隔离,使得求解器开发者只需关心数值算法,而无需关心与计算机硬件环境密切相关的并行模式。图8是设计的一种并行计算分层结构,由上至下分别是:并行API接口层、交界面数据层、数据底层(DataContainer)、MPI(Message Passing Interface)通信层。物理求解器开发者无须深厚的并行编程基础,通过调用头文件和静动态库,只需编写串行程序,通过调用并行API接口通信变量,就能自动完成并行求解器开发。

Figure 8 Hierarchical structure of parallel computing图8 并行分层结构示意图

为了满足第2条原则,使并行通信模式兼容结构/非结构求解器,图9设计了底层数据(即网格块交界面数据)通信模型[16],整个数据通信包括3个过程:数据压缩→MPI通信→数据解压。在这种数据交换模式中,将任意类型网格块的交界面数据按照接口标准压缩到数据容器DataContainer中(见第4节),不同进程间只进行“数据容器”底层数据的并行通信,将数据结构隔离在并行通信的底层,从而实现了任意类型网格的并行计算兼容性。

Figure 9 Communication model of underlying data图9 底层数据通信模型

PHengLEI软件中设计了2种异构并行方案:

(1) 基于“天河-2A”系统CPU+Matrix协处理器的MPI/OpenMP粗粒度异构并行(如图10所示)。根据“CPU+Matrix协处理器”的硬件架构,通信分2层进行:第1层是MPI通信,即CPU核之间或计算结点之间、基于网格1级分区交界面信息的MPI通信;第2层是OpenMP并行,即计算核心间、基于网格2级子分区的粗粒度Fork-Join并行,CPU和协处理器间采用COI/SCIF进行数据传输、控制。这里,1级分区和2级分区分别对应上文中的Region和Zone。之所以对CPU/Matrix异构系统采用粗粒度并行,是为了在保证规模可扩展的前提下,尽可能减小编程难度,将异构并行隔离至底层,实现CFD专家编程与异构并行无关。

Figure 10 Hybrid parallel model based on CPU/Matrix图10 CPU/Matrix协处理器异构并行架构

(2) 基于CPU+GPU的MPI/OpenACC细粒度异构并行(如图11所示)。GPU每个计算核心存储有限,不可能采用将Zone分配到线程的粗粒度并行模式,而是直接在GPU上对几何体遍历(图11中的Element几何体可以是点、面、单元),进行细粒度Fork-Join并行。为了减少CPU与GPU间的IO时间,迭代前,将计算过程中不变的几何数据结构拷贝至显存,在每步迭代中,仅将流场基本数据(密度、速度、压力)从显存拷贝出来。

Figure 11 Hybrid parallel model based on CPU/GPU图11 CPU/GPU异构并行架构

4 数据结构设计

数据结构是大型CFD软件的“灵魂”,数据流类似人体“血液”,对数据交换起着至关重要的作用。针对并行封装、结构/非结构耦合计算的需要,本文设计了一种能存储任意数据类型的数据容器DataContainer。

4.1 基本数据结构

在CFD软件运行过程中,会涉及到各种各样的数据读取,数据来源主要包括:控制参数、流场变量、湍流变量、网格信息、边界条件等。对于采用C++编程的CFD软件,数据类型不仅有常用的整型数(int)、单精度数(float)、双精度数(double)、字符串(string)等,还有标准库中的各种容器,如vector、list、set、map等,除此之外,还有自定义的多种数据类型。要想实现种类繁多的数据读写和存储,按照传统的方式需要对每种类型设计1个接口,对于大型软件来说无疑会带来冗余,且由于封装性不好,难以维护。

基本数据结构应满足软件的封装性要求,即无论何种类型的数据,对外的接口必须唯一。如图12所示,基本数据结构采用链表形式。链表是一种物理存储单元上非连续、非顺序的存储结构,动态生成的每个Data数据元素(“节点”)间通过指针与前后节点连接。为此将控制参数、流场变量等数据抽象为Data节点,由关键字、值、类型和数据大小构成,具体应用为:

(1)关键字:即string类型的变量名。

(2)值,即存储的变量指针,如迭代步数interation、马赫数Mach、雷诺数Re等单变量指针;流场压力、速度、温度等数组地址。

(3)类型:整型、字符、浮点、布尔。

(4)大小:即数据维度。标量为1,数组为其长度。

Figure 12 Basic data structure of the linked list图12 链表形式的基本数据结构

Figure 13 Design of DataContainer图13 数据容器DataContainer设计

大型通用CFD软件的一个重要基础是能够可靠、安全、高效地存取数据,数据流设计的合理性直接影响到软件平台设计的好坏和计算效率。实际上,图12所示的数据链表被抽象为CFD软件的“运行数据库(Running Data Base)”。在CFD软件运行过程中涉及到的所有数据均按照统一的规范存储于“运行数据库”之中,分别存储为1个链表数据结构形式的数据库。CFD软件中用到的数据库主要包括:

(1)计算控制参数数据库。存储迭代步数、计算状态参数、数值方法等参数,由主进程从文件中读入、解析后,分别发送至其他进程。

(2)流场变量数据库。存储密度、压力、速度、温度等流场数据,计算开始时各进程分别分配的内存,数据根据迭代过程随时更新。

(3)几何信息数据库。主要包括网格的几何信息,如网格点坐标、单元表面面积、单元体积、单元间或节点间的连接关系、并行网格分区间的对应关系等。

(4)边界条件数据库。对不同的每类物理边界存储参数(如物面、对称面、远场),分别构建不同数据库,并将数据库指针赋予每个边界面。

对于频繁存取的流场变量,非结构求解器采用多维数组(本质上是多维指针),结构求解器采用自定义的Fortran-style数组存储。这些数组也通过首地址,以链表形式存储于上述“运行数据库”。

此外,几何网格中涉及到的搜索查找操作,为提高其效率,采用ADT(Alternating Digital Tree)和哈希表数据结构。

4.2 数据容器

大规模并行CFD软件中存在多种数据交换,比较典型的有以下几种:多块结构网格交界面数据交换、并行分区交界面数据MPI通信、结构/非结构混合网格交界面数据交换(3.4节)、重叠网格重叠区数据交换、CPU与协处理器数据交换(3.6节)。如果对每种数据交换都分别写接口,则会极大地影响到软件的可读性、可扩展性和封装度。为此,本文设计了一种数据容器DataContainer,以将上述几种数据交换方式完全隔离至数据底层。

基本设计思想是将数据“标准化”,即:将整型、单/双精度浮点型、字符串等任意类型的数据转换为单字符数据,统一存储至容器;对于标准化后的数据,通过统一的接口实现读写数据操作、MPI接收/发送、异构系统的CPU/协处理器数据交换等。数据容器DataContainer设计图如图13所示。

5 结束语

如何适应下一代E级计算机硬件,如何在同1个软件上有机集成多物理模型,是PHengLEI软件设计面临的2个关键问题。国家数值风洞工程中,CFD软件规模大、结构复杂、物理模型多,限于篇幅,无法详细介绍,这其中,编程框架是团队开发的基础,计算域Zone/求解器Solver是软件的核心,并行框架直接关系硬件适应能力,数据结构关系软件可扩展性,本文从这几个方面介绍了最新的PHengLEI设计轮廓,回答了上述2个问题。

要说明的是,大型软件设计无法一蹴而就,在整体方案大体固定的情况下,要随着开发需求的变更而局部敏捷微调。例如,本文的并行框架,一开始只考虑了MPI并行,随着天河二号国产CPU/Matrix协处理器硬件需求的出现,重构了粗粒度异构并行框架,当考虑GPU加速后,又进一步重构了细粒度异构并行框架。未来的工作中,将采用“顶层设计+局部敏捷”的思路,持续更新软件架构,为国家数值风洞其他系统提供通用CFD软件。

致谢原空气动力研究与发展中心赫新研究员、陈亮中副研究员等人在风雷软件原型系统开发过程中做了开创性工作,国防科技大学计算机学院、广州超算中心、中国科学院网络中心等在软件设计过程中提供了帮助,在此一并感谢。

猜你喜欢
数据结构编程框架
框架
数据结构线上线下混合教学模式探讨
编程,是一种态度
元征X-431实测:奔驰发动机编程
编程小能手
广义框架的不相交性
纺织机上诞生的编程
为什么会有“数据结构”?
高职高专数据结构教学改革探讨
关于原点对称的不规则Gabor框架的构造