elsa开发手册

1 空间离散后为ODE,采用(伪)unsteady时间积分求解器,进入(伪)时间循环

1.1在这个循环内部

2 实现

3 输入数据

4 用户界面

5 并行

6 多目标耦合

7 优化

8 后处理

9 Kernel 设计

9.1 职责分类

9.2 layers

elsA kernel包括400个class,分配到26个modules.这些模块又归于6个layer,上层只依赖下层,单向职责.

9.2.1 Base由以下模块组成

9.2.2 Geometry Layer

9.2.3 Physical model层

9.2.4 空间离散 layer

9.2.5 Solve layer, kernel最复杂的部分,

9.2.6 Factory (elsA 顶层layer)

10 部件详述

10.1 FLD 部件

10.1.1基本的数值容器

Fields是elsA最基本的操作对象,作为real,integer,boolean的容器.用后缀表示版本,F代表Float,I,B.


00001:   typedef FldFieldF FldCellF
10.1.2 接口

fileld定义为2D结构.

10.1.2.1. Construction of a field which stores the unknowns of the CFD problem (ro, rou, rov, row, roE):

E_Int nfld = 5; FldCellF wCons(ncell, nfld); Construction of a field which stores fluxes: FldIntF flux(3*ncell, nfld);

10.1.2.2. Construction of a field which stores mesh coordinates:

FldNodeF x(ncell, 3); FldNodeF y(ncell, 3); FldNodeF z(ncell, 3);

10.1.2.3. FldArray or FldField can be used to store values without geometric links, such as:

FldArrayF TurKO::getModConst() const { FldArrayF modConst (7); modConst[0] = _kappa; modConst1 = _sigma1; modConst2 = _sigmae1; modConst3 = _beta1; modConst4 = _wsig1; modConst5 = _betae; modConst6 = _Sr; }

10.1.2.4. To access individual elements, a syntax similar to Fortran is used:

FldArrayF f(100,2); f(3,2)=3.14159; // assigns pi to the fourth element of component 2 FldArrayF g(100); g[0] = 2.22;

10.1.3 内存

Fld 比c/c++数组的优势

10.1.4 传递field数据给Fortran

传递数据给Fortran77函数.通过给FldField动态分配的内存地址

10.1.4.1 FldArray 内部结构

FldArray在一个连续的内存空间存储数据,为动态分配的.我们可以认为它是c 指针管理内存的wrapper._data指向这块内存.这种1D的布局和传统的Fortran和c代码一致.


00001: //返回第fld物理变量的第l个节点数据,按_nfld存
00002: inline E_Float
00003: FldArrayF::operator()(E_Int l, E_Int fld) const
00004: {
00005:   return (_data[l + (fld-1)*_size]);
00006: }
00007: 
00008: //We would have the transpose (or swapped) implementation:
00009: //另外一种的存储索引方式,按l存
00010: inline E_Float
00011: FldArrayF::operator()(E_Int l, E_Int fld) const
00012: {
00013:   return (_data[fld-1 + l*_nfld]);
00014: }
00015: 
10.1.4.2 例子

在fortran中定义


00001: extern "C"
00002: {
00003: void
00004: denconvec_(const E_Int& ncell, const E_Int& neqtot, const E_Int& neq,
00005:            const E_Int& ro, const E_Int& rou, const E_Int& roe,
00006:            const E_Int& rog, const E_Int& roug, const E_Int& roeg,
00007:            const E_Float* consvar, const E_Float* press,
00008:            E_Float* fdx, E_Float* fdy, E_Float* fdz);
00009: }
00010: 

在C++中使用


00001: denconvec_(ncell, neqTot, nbEqMoyComp,
00002:            rho, mom, ene, rhoG, momG, eneG,
00003:            wCons.begin(), press.begin(),
00004:            fdx.begin(), fdy.begin(), fdz.begin() );

00001: fdX(      0,1), fdX(0,2), fdX(0,3),..., fdX(      0,neq),
00002: ...,
00003: fdX(ncell-1,1), ...,                    fdX(ncell-1,neq)

00001: fdX(0, 1), fdX(1,1),fdX(2,1),..., fdX(ncell-1, 1),
00002: ...,
00003: fdX(0,neq),...,                   fdX(ncell-1,neq)

00001:       SUBROUTINE denconvec(ncell, neqtot, neq,
00002:     &                          ro, rou, roe,
00003:     &                          rog, roug, roeg,
00004:     &                          w, p,
00005:     &                          fdx, fdy,     fdz)
00006:          IMPLICIT NONE
00007: C_IN
00008:          INTEGER_E ncell, neqtot, neq
00009:          REAL_E        w(0:ncell-1,neqtot)     ! Conservative Variables
00010:          REAL_E        p(0:ncell-1)            ! Pressure
00011: C_OUT
00012:          REAL_E        fdx(0:ncell-1,neq)      ! Convective Flux      X-Component
00013:          REAL_E        fdy(0:ncell-1,neq)      ! Convective Flux      Y-Component
00014:          REAL_E        fdz(0:ncell-1,neq)      ! Convective Flux      Z-Component
00015:          [.......]
00016:          DO icell = 0, ncell-1
00017:             roi = ONE / w(icell,rog)
00018:             fdx(icell,ro)      = w(icell,roug)
00019:             fdy(icell,ro)      = w(icell,rovg)
00020:             fdz(icell,ro)      = w(icell,rowg)
00021:          [.......]

10.2 GEO 部件

GeoGrid在kernel中广泛使用,因为很多的CFD类需要一个指向GeoGrid的指针.GeoGrid为GeoGridMetrics和GeoConnect的组合.他们负责

10.2.1 Ghost 几何元素

通过如下控制Ghost

10.2.1.1 Ghost cell numbering

• GHOST_I1 ghost cells in IMIN(代表i的最小index), GHOST_I2 ghost cells in IMAX(代表i的最大index), • GHOST_J1 ghost cells in JMIN, GHOST_J2 ghost cells in JMAX, • GHOST_K1 ghost cells in KMIN, GHOST_K2 ghost cells in KMAX.

10.2.1.2 Ghost interface numbering

• GHOST_I1 ghost interfaces in IMIN, GHOST_I2-1 ghost interface in IMAX, • GHOST_J1 ghost interfaces in JMIN, GHOST_J2-1 ghost interface in JMAX, • GHOST_K1 ghost interfaces in KMIN, GHOST_K2-1 ghost interface in KMAX.

10.2.1.3 Ghost node (mesh points) numbering

• GHOST_I1 ghost nodes in IMIN, GHOST_I2-1 ghost node in IMAX, • GHOST_J1 ghost nodes in JMIN, GHOST_J2-1 ghost node in JMAX, • GHOST_K1 ghost nodes in KMIN, GHOST_K2-1 ghost node in KMAX.

10.2.1.4 Ghost defaultvalues

The default values are: GHOST_I1 = 2; GHOST_I2 = 2; GHOST_J1 = 2; GHOST_J2 = 2; GHOST_K1 = 2; GHOST_K2 = 2;

10.2.1.5 cell/interface/node的分辨

上述定义的好处就是我们在cell,interface和node的index之间关系简化,使得我们在他们中循环很方便.我们在i,j,k方向上的cells,nodes和interface数目完全相同.


00001: DO n=n0cell, nfcell                  ! loop on cells
00002:   ni1 = n                            ! "i" interface (left)
00003:   nj1 = n +   ncell                  ! "j" interface (down),ncell是所有的cell个数,因为先存i,后存j,再存k
00004:   nk1 = n + 2*ncell                  ! "k" interface (back)
00005:   ....
00006:   ni2 = n +           inccell(1,0,0) ! "i" interface (right
00007:   nj2 = n +   ncell + inccell(0,1,0) ! "j" interface (up)
00008:   nk2 = n + 2*ncell + inccell(0,0,1) ! "k" interface (front)
00009: 

00001: inline E_Int
00002: GeoConnect::getNbCell() const
00003: {
00004:   return ((_im - 1 + GHOST_I1 + GHOST_I2)*
00005:           (_jm - 1 + GHOST_J1 + GHOST_J2)*
00006:           (_km - 1 + GHOST_K1 + GHOST_K2));
00007: }
00008: inline E_Int
00009: GeoConnect::getNbInti() const
00010: {
00011:   return getNbCell();
00012: }

湍流模型

抽象类
计算方式分类

Oper 部件

Operator的类主要为空间离散.每一个operator都必须计算一个定义在特殊几何体(cell或者interface)上的Fld-FieldF对象.

Oper 模块
OperBase抽象类

OperBase为抽象类.比较重要的属性:


00001:  virtual void prepare(const EosSysEq&, EosElemSysType,EosIdealGas* eos, const GeoGridBase* grid);

prepare函数用于初始化这些指针.

继承自OperBase的类有两种

OperGrad类

继承自OperBase.


00001:   // compute the gradient of the conservative variables
00002:   void compute( FldCellF& fldOut,
00003:                 const list<BndPhys*>& listBnd,
00004:                 const list<JoinBase*>& listJoin,
00005:                 AuxField identOfField = MISC);
00006: 
00007:   // compute the gradient of non conservative variables (?)
00008:   virtual void compute( FldCellF& fldOut,
00009:                         const list<BndPhys*>& listBnd,
00010:                         const list<JoinBase*>& listJoin,
00011:                         const FldCellF& fldIn,
00012:                         AuxField identOfField);

梯度和flux计算在所有的cell和interfaces上使用相同的数值算法计算.但是标准的计算公式会在border区域给出错误的结果.所以operator对象需要和boundary对象协作.

OperTerm抽象类

计算OperTerm分为两步

  1. 计算所有需要的附属场值(通过守恒变量)
  2. 计算fluxes和source term(使用第一步计算的数值)

    OperTerm::_setOfIdent为list<AuxField>类型,用于识别什么样的附属计算需要进行.computeAllField调用computeFiled()函数计算所有的注册过的附属场.


00001:   virtual void computeAllField(const list<BndPhys*>* listBnd = E_NULLPTR,
00002:                               const list<JoinBase*>* listJoin = E_NULLPTR);
00003: 
00004:   virtual void computeField(AuxField identOfField,
00005:                            const list<BndPhys*>* listBnd = E_NULLPTR,
00006:                            const list<JoinBase*>* listJoin = E_NULLPTR);

Flus和source在这一个阶段还没有计算,下一节介绍.

OperFlux抽象类

继承自OperTerm,使用上面介绍的策略1实现了主要的compute()方法.


00001:   void OperFlux::compute( FldIntF& fldOut,
00002:                           const list<BndPhys*>& listBnd,
00003:                           const list<JoinBase*>* listJoin )
00004: {
00005:    compFlux(...);
00006:    computeAllBorders(...);
00007: }
00008: 

定义了flux类最重要的抽象方法compFlx.知道了cell center上的守恒变量,这个方法提供了interfaces上的flux.


00001:   virtual void compFlux(const FldCellF& fldIn,FldIntF& fldOut) = 0;

OperFlux还定义了另外一个重要的方法:computeAllBorders(),这个方法用于计算边界区域的flux,并且考虑边界条件.所有的物理边界,使用下述的思想:

  1. 定义在边界interfaces上的vector wb1的计算代理给了BndPhys* 对象,它负责处理边界
  2. wb1 然后被用来修正边界interface的flux计算.具体的实现由特定的flux类决定.
OperSou 抽象类

OperSou是source term的抽象类.这个类继承自OperTerm类.

Fxc 模块
Fxd 模块
Sou 模块
Valid XHTML 1.0 :: Valid CSS :: Made with Emacs-Muse