← 首页← Home

二维 RANS–SA 方程的离散伴随:格点格式,伴随不一致的远场

Discrete adjoints for two-dimensional RANS–SA: node-centred, adjoint-inconsistent far field

方程是可压缩 RANS 与标准 Spalart–Allmaras 湍流模型:每个节点有 5 个未知量 (ρ, ρu, ρv, ρE, ρν̃)。算例是二维对流页面的同一张环形混合网格:内圈是物面,外圈是远场,贴壁一层四边形、外层三角形。物面是无滑移、绝热壁面(强条件,替换壁面节点的三行残差),远场分成来流与出口两部分:来流给定 ρ、u、v、ν̃(T 自由、热流为零),出口是牵引力出口(总牵引力 p n − τ·n 等于 p∞n)。空间离散:Roe 通量、无权最小二乘重构(不加限制器)、SU2 式的边上修正平均梯度粘性通量;求解:伪时间 + 对称块 Gauss–Seidel,近似 Jacobian 是一阶 Roe 加薄剪切层。本页的主线是离散伴随:先把残差拆成几遍循环,再把同样的循环改写成 matrix-free 前向(R˙=AU˙)和 matrix-free 伴随(Uˉ=ATRˉ),最后用前向、复数步长与差分三种独立办法核对伴随给出的导数。附录 A 从同一个连续问题出发推导并求解连续伴随,在逐级加密的网格上与离散伴随比较。本页的来流边界沿用原来的处理,它是伴随不一致的:离散伴随在来流边界附近不趋于连续伴随。附录 B 说明原因,并与伴随一致的版本逐级比较。页首可以切换一阶/二阶空间离散,下面所有演示都随之重算。相关页面:同一问题的格心版本只换了控制体;本系列的一维 Burgers 入门从最简单的方程讲离散伴随的整套做法(残差、matrix-free 前向与伴随、Gauss–Seidel、差分与复数步长),二维 Euler 在同一张网格上处理无粘方程组(它用 Rusanov 通量,本页换成 Roe 通量),二维层流 Navier–Stokes 加上粘性通量与无滑移壁(它的梯度重构与粘性通量离散和本页不同)。

The equations are compressible RANS with the standard Spalart–Allmaras model: every node carries 5 unknowns (ρ, ρu, ρv, ρE, ρν̃). The test case is the same annular hybrid mesh as the two-dimensional advection pages: the body on the inner ring, the far field on the outer, quadrilaterals in the layer against the wall and triangles outside. The body is a no-slip, adiabatic wall (a strong condition, replacing three rows of each wall node's residual), and the far field has two parts: the inflow fixes ρ, u, v and ν̃ (T is free, with zero heat flux), and the outlet is a traction outlet (the total traction p n − τ·n equals p∞n). Spatial discretisation: the Roe flux, unweighted least-squares reconstruction (no limiter), and SU2's corrected average gradient on the edges for the viscous flux; the solver: pseudo-time with symmetric block Gauss–Seidel, on an approximate Jacobian made of first-order Roe and the thin shear layer. The main line of this page is the discrete adjoint: it splits the residual into passes, rewrites the same passes as the matrix-free tangent (R˙=AU˙) and the matrix-free adjoint (Uˉ=ATRˉ), and checks the adjoint's derivatives three independent ways: the tangent, the complex step, and finite differences. Appendix A derives and solves the continuous adjoint of the same continuous problem and compares it with the discrete adjoint on a sequence of refined meshes. This page keeps the original treatment of the inflow boundary, which is adjoint-inconsistent: near the inflow the discrete adjoint does not approach the continuous one. Appendix B explains why and compares level by level with the adjoint-consistent version. The header switches between first- and second-order spatial discretisation, and every demo below is recomputed. Related pages: the cell-centred version of the same problem changes the control volumes only; in this series, the 1-D Burgers introduction walks through the whole discrete-adjoint method on the simplest equation (residual, matrix-free tangent and adjoint, Gauss–Seidel, finite differences and the complex step), 2-D Euler treats the inviscid system on this same mesh (with a Rusanov flux, where this page uses Roe's), and 2-D laminar Navier–Stokes adds the viscous flux and the no-slip wall (with a gradient reconstruction and a viscous discretisation different from this page's).

全页路线图:从设计输入到梯度设计输入 DD = (α, M, μref, X)51 个分量(3 + 48)第 12 节求解R(U) = 0伪时间 + 对称块Gauss–Seidel第 5、6 节状态 U120 个未知量24 个节点 × 5第 2 节目标 CD阻力系数g = ∂CD/∂U第 7 节梯度 dCD/dD51 个分量第 12 节前向(tangent)路线:从左往右,每个设计分量一次f = ∂R/∂DD 的右端项Av = −f一次线性求解v = U˙​状态的切向量C˙D = ∂CD/∂D + gTv方向导数dCD/dD梯度的一个分量51 个设计分量 → 51 次线性求解,每次得到梯度的一个分量(第 8、10 节)伴随(adjoint)路线:从右往左,只解一次dCD/dD = ∂CD/∂D + ψTf全部 51 个分量ψ伴随变量ATψ = −g一次转置求解g = ∂CD/∂U目标对状态的导数1 次转置求解,再做乘积 ψTf(不再求解),得到全部 51 个分量(第 9、11、12 节)代价:51 个设计分量 ⇒ 前向 51 次线性求解,伴随 1 次全页路线图:从设计输入到梯度原始计算前向 ×51伴随 ×1从上往下从下往上设计输入 D51 个分量第 12 节求解R(U) = 0第 5、6 节状态 U120 个未知量第 2 节目标 CDg = ∂CD/∂U第 7 节梯度 dCD/dD51 个分量第 12 节f = ∂R/∂DD 的右端项Av = −f一次线性求解v = U˙​状态的切向量C˙D = ∂CD/∂D+gTv方向导数dCD/dD梯度的一个分量dCD/dD =∂CD/∂D + ψTf全部 51 个分量ψ伴随变量ATψ = −g一次转置求解g = ∂CD/∂U目标对状态的导数51 个设计分量:前向 51 次线性求解,伴随 1 次
Page roadmap: from the design input to the gradientdesign input DD = (α, M, μref, X)51 components(3 + 48)Section 12solveR(U) = 0pseudo-time +symmetric block GSSections 5–6state U120 unknowns24 nodes × 5Section 2objective CDdrag coefficientg = ∂CD/∂USection 7gradient dCD/dD51 componentsSection 12Tangent (forward) route: left to right, once per design componentf = ∂R/∂Dright-hand side for DAv = −fone linear solvev = U˙​tangent of the stateC˙D = ∂CD/∂D + gTvdirectional derivativedCD/dDone gradient component51 design components → 51 linear solves, each giving one gradient component (Sections 8 and 10)Adjoint route: right to left, a single solvedCD/dD = ∂CD/∂D + ψTfall 51 componentsψadjoint variableATψ = −gone transposed solveg = ∂CD/∂Uobjective vs state1 transposed solve, then the product ψTf (no further solve) gives all 51 components (Sections 9, 11 and 12)Cost: 51 design components ⇒ 51 tangent solves against 1 adjoint solvePage roadmap: from the design input to the gradientPrimalTangent ×51Adjoint ×1top to bottombottom to topdesign input D51 componentsSection 12solveR(U) = 0Sections 5–6state U120 unknownsSection 2objective CDg = ∂CD/∂USection 7gradient dCD/dD51 componentsSection 12f = ∂R/∂DRHS for DAv = −fone linear solvev = U˙​state tangentC˙D = ∂CD/∂D+gTvalong DdCD/dDone componentdCD/dD =∂CD/∂D + ψTfall 51 componentsψadjoint variableATψ = −gtransposed solveg = ∂CD/∂Uobjective vs state51 design components:51 tangent solves, 1 adjoint solve
全页路线图 · 从设计输入到梯度。上排是原始计算:由设计输入求解离散方程,得到状态,再算出目标。前向(tangent)路线顺着计算方向,每个设计分量解一次线性方程,得到梯度的一个分量;伴随(adjoint)路线逆着计算方向,只解一次转置方程,再做一次乘积就得到全部分量。本页默认设置下有 51 个设计分量:51 次前向求解对 1 次伴随求解。方框下方的节号可以点击。Page roadmap · From the design input to the gradient. The top row is the primal computation: solve the discrete equations for the design input, obtain the state, then evaluate the objective. The tangent (forward) route follows the direction of computation and solves one linear system per design component, each giving one gradient component; the adjoint route runs against it, solves a single transposed system and obtains every component with one more product. With this page's default settings there are 51 design components: 51 tangent solves against one adjoint solve. The section numbers under the boxes are links.

第 1 节Section 1

方程:可压缩 RANS 方程与 Spalart–Allmaras 模型

The equations: compressible RANS with the Spalart–Allmaras model

从守恒律到定常 RANS–SA 方程

From conservation laws to the steady RANS–SA equations

本页的方程描述可压缩气体绕物体的湍流。质量、动量、能量守恒给出 Navier–Stokes 方程;湍流在很小的尺度上快速脉动,工程计算只求平均流(雷诺平均,RANS)。平均后多出脉动造成的动量与热量输运(雷诺应力),方程不再封闭。涡粘性假设把它写成附加的粘度 μt,加到分子粘度上,并按湍流普朗特数 Prt 加到导热上;Spalart–Allmaras(SA)模型用工作变量 ν̃ 的一个输运方程给出 μt。于是每个点有 5 个未知量 (ρ, ρu, ρv, ρE, ρν̃),比二维层流 N–S 多一个。

The equations of this page describe turbulent flow of a compressible gas around a body. Conservation of mass, momentum and energy gives the Navier–Stokes equations; turbulence fluctuates rapidly on small scales, and engineering calculations solve for the mean flow only (Reynolds averaging, RANS). Averaging leaves an extra transport of momentum and heat by the fluctuations (the Reynolds stresses), and the equations are no longer closed. The eddy-viscosity hypothesis writes it as an added viscosity μt, added to the molecular one and, through a turbulent Prandtl number Prt, to the heat conduction; the Spalart–Allmaras (SA) model supplies μt through one transport equation for a working variable ν̃. Every point then carries 5 unknowns (ρ, ρu, ρv, ρE, ρν̃), one more than two-dimensional laminar N–S.

守恒形式的 RANS–SA 方程,带时间项:

RANS–SA in conservation form, with the time term:

∂U∂t+∇⋅(𝐅c(U)−𝐅v(U,∇U))=S(U,∇U,d),U=(ρρuρvρEρν~)

本页要的是定常解:∂U/∂t = 0,于是 ∇·(Fc − Fv) = S。时间项仍然要写出来,因为定常解正是靠伪时间推进得到的:从初始状态出发沿 t 推进,直到时间导数消失(第 6 节)。这里的 t 是伪时间,每个控制体取自己的步长,所以推进的中间状态不是真实的时间历程,只有推进到底得到的定常解才有物理意义。

This page wants the steady solution: ∂U/∂t = 0, so that ∇·(Fc − Fv) = S. The time term is still written, because the steady solution is reached by pseudo-time marching: from an initial state, U is advanced in t until the time derivative vanishes (Section 6). Here t is a pseudo time and every control volume takes its own step, so the intermediate states are not a physical time history; only the steady solution the marching ends at has a physical meaning.

对流通量是 Euler 通量加上随质量通量走的 ρν̃;粘性通量是应力、热流与 SA 的扩散:

The convective flux is the Euler flux plus ρν̃ carried by the mass flux; the viscous flux holds the stress, the heat flux and the SA diffusion:

𝐅c ⁣⋅n=(ρqρuq+p nxρvq+p nyρHqρν~q),𝐅v ⁣⋅n=(0(τn)x(τn)yu⋅τn+ke∇T⋅nρa ∇ν~⋅n),q=u⋅n

其中 p=ρT(取 R=1、cv=2.5、cp=3.5,所以 γ=1.4),μ(T)=μref 1.4 T1.5/(T+0.4)(Sutherland),湍流粘度 μt=ρν~fv1(χ),χ=ρν~/μ,

with p=ρT (R=1, cv=2.5, cp=3.5, so γ=1.4), μ(T)=μref 1.4 T1.5/(T+0.4) (Sutherland), the eddy viscosity μt=ρν~fv1(χ) with χ=ρν~/μ, and

τ=(μ+μt)(∇u+∇uT−23(∇⋅u)I),ke=cp(μPr+μtPrt),ρa=μ+ρν~σ

Pr=0.72、Prt=0.9、σ=2/3。源项只在第 5 个方程里,是 NASA TMR 给出的 SA 守恒形式(密度梯度项不能丢):

Pr=0.72, Prt=0.9, σ=2/3. The source sits in the fifth equation only; it is the conservative form of the SA model given by NASA's TMR (the density-gradient term must not be dropped):

S5=−a ∇ρ⋅∇ν~+ρ cb2σ∣∇ν~∣2+ρ[cb1(1−ft2)S~ν~−(cw1fw−cb1κ2ft2)(ν~d)2]

模型函数取标准(非负)版本:

The model functions are the standard (not the negative) version:

fv1=χ3χ3+cv13,fv2=1−χ1+χfv1,ft2=ct3e−ct4χ2,B=ν~fv2κ2d2
S~={Ω+B,B≥−c2ΩΩ+Ω (c22Ω+c3B)(c3−2c2)Ω−B,B<−c2Ωr=min⁡ ⁣(ν~κ2d2S~, 10),g=r+cw2(r6−r),fw=g(1+cw36g6+cw36)1/6

Ω = |∂v/∂x − ∂u/∂y| 是涡量的大小;常数 cb1 = 0.1355、cb2 = 0.622、κ = 0.41、cw2 = 0.3、cw3 = 2、cv1 = 7.1、ct3 = 1.2、ct4 = 0.5、c2 = 0.7、c3 = 0.9,cw1 = cb1/κ² + (1 + cb2)/σ。

Ω = |∂v/∂x − ∂u/∂y| is the size of the vorticity; the constants are cb1 = 0.1355, cb2 = 0.622, κ = 0.41, cw2 = 0.3, cw3 = 2, cv1 = 7.1, ct3 = 1.2, ct4 = 0.5, c2 = 0.7, c3 = 0.9, and cw1 = cb1/κ² + (1 + cb2)/σ.

模型、常数与守恒形式取自 Spalart 与 Allmaras(1994)、Allmaras、Johnson 与 Spalart(2012)以及 NASA 的湍流模型资源网站 TMR;第 3 节的 Roe 通量见 Roe(1981),粘性通量的修正平均梯度与格点页的边式格式见 SU2(Economon 等,2016)。书目列在附录 A 末尾。

The model, its constants and the conservative form follow Spalart and Allmaras (1994), Allmaras, Johnson and Spalart (2012) and NASA's Turbulence Modeling Resource (TMR); the Roe flux of Section 3 is Roe's (1981), and the corrected average gradient of the viscous flux and the node page's edge-based scheme are SU2's (Economon et al., 2016). The references are listed at the end of Appendix A.

这些函数各有来由。ν̃ 是 SA 的工作变量:离开壁面它就是涡粘性 νt = μt/ρ(fv1 → 1);靠近壁面 fv1 把它压低,νt = ν̃fv1(χ),于是 ν̃ 一直到壁面都随 d 线性变化,比 νt 容易算准。方程右端是生成减耗散:湍流由剪切产生,所以生成项与涡量 S̃ 成正比;壁面限制涡的尺度,所以耗散项按 (ν̃/d)² 增长。S̃ = Ω + ν̃fv2/(κ²d²) 在对数层里等于 uτ/(κd),fv2 让这一关系一直保持到壁面。r = ν̃/(S̃κ²d²) 比较湍流的长度尺度与壁面距离:对数层里 r = 1、fw = 1;离壁面越远 r 越大,fw 趋于常数 (1 + cw36)1/6 ≈ 2.0,所以把 r 截断在 10 并不改变模型,只免得 r6 溢出。ft2 的两项让 ν̃ = 0 成为一个稳定的解,层流区因此不会自己转捩。χ 略大于 1 时 fv2 变负,B 随之为负,Ω + B 可能小于零;2012 年的修正在 B < −c2Ω 时换成第二个式子,它与第一支在 B = −c2Ω 处值与一阶导数都相接,并让 S̃ 始终大于 0.1Ω。

Each of these functions has a purpose. ν̃ is SA's working variable: away from walls it is the eddy viscosity νt = μt/ρ (fv1 → 1); near a wall fv1 damps it, νt = ν̃fv1(χ), so that ν̃ varies linearly with d all the way to the wall and is easier to compute accurately than νt. The right-hand side is production minus destruction: turbulence is produced by shear, so production is proportional to the vorticity S̃; the wall limits the size of the eddies, so destruction grows as (ν̃/d)². S̃ = Ω + ν̃fv2/(κ²d²) equals uτ/(κd) in the log layer, and fv2 keeps that relation all the way to the wall. r = ν̃/(S̃κ²d²) compares the turbulent length scale with the wall distance: r = 1 and fw = 1 in the log layer; further from the wall r grows and fw tends to the constant (1 + cw36)1/6 ≈ 2.0, so capping r at 10 does not change the model and only keeps r6 from overflowing. The two ft2 terms make ν̃ = 0 a stable solution, so a laminar region does not turn turbulent by itself. For χ slightly above 1, fv2 turns negative, B with it, and Ω + B can drop below zero; the 2012 modification switches to the second expression for B < −c2Ω, which meets the first branch at B = −c2Ω in value and first derivative and keeps S̃ above 0.1Ω.

波速与边界条件

Wave speeds and boundary conditions

对流部分决定信息怎样传播。沿单位法向 n,对流通量 Jacobian 的五个特征值是两道声波 q ∓ c(c 是声速),以及都以 q = u·n 移动的熵波、剪切波和 ν̃ 波;本页 M = 0.2,处处亚声速。n 指向区域外时,特征值为负的波从外面进来;无粘极限下,边界上能给定几个值就看进来几道波:来流(q < 0)四道,出口(q > 0)一道。粘性项还要一些条件:来流给定 ρ、u、v、ν̃,T 自由、热流为零;出口给定牵引力 p n − τ·n = p∞n,热流与 ν̃ 的扩散通量为零;物面无滑移、绝热,ν̃ = 0。第 4 节的图 4.2 逐个边界数这些条件,同一节写出它们的离散。

The convective part decides how information travels. Along a unit normal n the five eigenvalues of the convective flux Jacobian are the acoustic waves q ∓ c (c the speed of sound) and the entropy, shear and ν̃ waves, all three at q = u·n; at M = 0.2 the flow is subsonic everywhere. With n pointing out of the domain, a wave with a negative eigenvalue comes in, and in the inviscid limit a boundary takes as many values as waves come in: four at the inflow (q < 0), one at the outlet (q > 0). The viscous terms need a few more: the inflow gives ρ, u, v and ν̃, with T free and zero heat flux; the outlet gives the traction p n − τ·n = p∞n and zero heat and ν̃ diffusive fluxes; the body is no-slip and adiabatic, with ν̃ = 0. Figure 4.2 counts these conditions boundary by boundary, and Section 4 writes out their discretisation.

四个 RANS–SA 页面解同一个连续问题:格心、格点两种控制体,各有两种来流边界的离散;同一种控制体的两个页面只在来流边界的离散上不同。本页沿用原来的处理:来流节点的 ρ、ρu、ρv、ρν̃ 四行换成 U − U∞;伴随一致的版本里,来流节点保留质量行,只以节点自己的 ρ 固定 u、v、ν̃。两者都给出各自离散问题的精确导数;区别在于加密时离散伴随在来流附近是否趋于连续伴随(伴随一致性)。做法见第 4 节,原因与逐级比较见附录 B。

The four RANS–SA pages solve the same continuous problem: two kinds of control volume, each with two discretisations of the inflow boundary; the two pages of one kind differ only in the inflow discretisation. This page keeps the original treatment: the ρ, ρu, ρv and ρν̃ rows of an inflow node are replaced by U − U∞; in the adjoint-consistent version an inflow node keeps its mass row and fixes u, v and ν̃ at its own ρ. Both give the exact derivatives of their own discrete problems; they differ in whether, under refinement, the discrete adjoint approaches the continuous one near the inflow (adjoint consistency). Section 4 gives the two treatments, Appendix B the reason and a level-by-level comparison.

本页的问题

The problem on this page

区域是物体与远场之间的环:物体是凸八边形(弦长 1.1),远场是半径 1.9 的正八边形,第 2 节的网格填满两者之间。来流取 ρ∞ = T∞ = p∞ = 1,于是声速 c∞ = √γ,U∞ = M√γ。按伴随优化文献的通常写法,设计变量记作 D = (α, M, μref, X),共 51 个,X 是 24 个节点的 48 个坐标;目标函数是第 7 节的阻力系数 CD(下标 D 指阻力,不是设计变量)。基线解是页首默认设置(二阶)下 R(U) = 0 的收敛解(第 6 节),CD = 54.2003,这张粗网格上的阻力有多准见第 7 节。图 1.1 把这些画在一起。

The domain is the ring between the body, a convex octagon (chord 1.1), and the far field, a regular octagon of radius 1.9; the mesh of Section 2 fills it. The free stream has ρ∞ = T∞ = p∞ = 1, so c∞ = √γ and U∞ = M√γ. As is usual in the adjoint-optimization literature, the design variables are written D = (α, M, μref, X), 51 in all, with X the 48 coordinates of the 24 nodes; the objective is the drag coefficient CD of Section 7 (the subscript D stands for drag, not for the design). The baseline is the converged solution of R(U) = 0 at the header's default settings (second order; Section 6), with CD = 54.2003; Section 7 discusses how accurate the drag of this coarse mesh is. Figure 1.1 draws all of this.

物体bodyU∞, αeDM = 0.2, α = 5°, ρ∞ = T∞ = p∞ = 1μref = 0.02, Re ≈ 13, ν̃∞ = 3ν∞来流:给定 ρ、u、v、ν̃;T 自由,热流为零inflow: ρ, u, v, ν̃ given; T free, zero heat flux出口:p n − τ·n = p∞n,热流与 ν̃ 的扩散通量为零outlet: p n − τ·n = p∞n; no heat or ν̃ diffusive flux物面:u = v = 0,ν̃ = 0,绝热wall: u = v = 0, ν̃ = 0, adiabatic来流与出口的交界点where the inflow meets the outlet未知量 U:24 个节点 × 5 = 120unknowns U: 24 nodes × 5 = 120设计变量 D:α、M、μref 与 48 个坐标,共 51 个design D: α, M, μref and 48 coordinates (51)CD = F·eD/q∞基线解(第 0 级网格,二阶):CD = 54.2003baseline (level-0 mesh, second order): CD = 54.2003
图 1.1 · 本页的问题一览(格点,第 0 级网格)。区域是物体(琥珀色的凸八边形,无滑移绝热壁)与远场八边形之间的环;远场按 u∞·n 的符号分成来流(实线)与出口(虚线),紫点是两者的交界。U∞ 是来流(迎角 α),eD 是阻力方向。右边:来流的数(Re 以物体弦长 1.1 计)、三种边界、未知量、设计变量与目标,都由本页代码在构建时算出。Figure 1.1 · The problem on this page at a glance (node-centred, level-0 mesh). The domain is the ring between the body (the amber convex octagon, a no-slip adiabatic wall) and the far-field octagon; the far field is split by the sign of u∞·n into the inflow (solid) and the outlet (dashed), and the violet dots mark where they meet. U∞ is the free stream (angle of attack α), eD the drag direction. On the right: the free stream (Re on the body's chord of 1.1), the three kinds of boundary, the unknowns, the design variables and the objective, all computed by this page's code at build time.

本页的流动:M = 0.2,迎角 5°,μref = 0.02(以物体弦长 1.1 计 Re ≈ 13),来流 ν̃∞ = 3ν∞。出口是牵引力出口,定常尾迹必须顺着出口流出、不能倒流:第 4 级网格上出口的 u·n 最小为 0.07U∞,处处向外。整个区域绝热(壁面、来流、出口都没有热流),粘性加热只能随出口的流动带走,所以温度整体高于来流的 T∞ = 1:第 4 级网格上 T 在 [1.021, 1.099] 之间(来流面上 T 不给定,热也会向上游传到那里)。这样的网格分辨不了真实的高雷诺数边界层;这里要的是一个用得到模型各个分支、又能收敛到舍入误差的离散问题:r 的截断(S̃ 的修正分支在本页只出现在 ν̃ 行被替换的来流节点上,残差用不到它;第 4 节列出两者的控制体数),以及涡粘性:来流状态 χ = 3,μt/μ = 0.21;本页(第 0 级网格)各控制体上 μt/μ 最大 0.092(χ 最大 2.42):χ = ν̃/ν,ν = μ/ρ;区域里 ν̃ 不超过来流值,而 ν 处处至少是来流的 1.24 倍,所以 χ 比来流小。

The flow on this page: M = 0.2, 5° angle of attack, μref = 0.02 (Re ≈ 13 on the body's chord of 1.1), and ν̃∞ = 3ν∞ at the inflow. The outlet is a traction outlet, and the steady wake must leave through it without flowing back: on level 4 the outlet's smallest u·n is 0.07U∞, outward everywhere. The whole domain is adiabatic (no heat flux through the wall, the inflow or the outlet), so the viscous heating can only leave with the outflow, and the temperature lies above the free stream's T∞ = 1 throughout: on level 4, T is between 1.021 and 1.099 (T is not prescribed on the inflow faces, and heat reaches them upstream too). A mesh like this cannot resolve a real high-Reynolds boundary layer; the aim is a discrete problem that exercises the branches of the model and still converges to round-off: the cap on r (on this page the modified branch of S̃ occurs only at inflow nodes, whose ν̃ rows are replaced, so the residual does not use it; Section 4 counts the control volumes of both), and the eddy viscosity: at the inflow state χ = 3 and μt/μ = 0.21; over the control volumes of this page (the level-0 mesh) μt/μ is at most 0.092 (χ at most 2.42): χ = ν̃/ν with ν = μ/ρ, and inside the domain ν̃ does not exceed its inflow value while ν is everywhere at least 1.24 times the inflow's, so χ stays below the inflow's.

这组方程的作用

What these equations are for

在流体力学里,RANS 加一个湍流模型是计算飞机、叶轮机械等高雷诺数定常流动的常用办法:不解析每一个涡,只算平均流,一次计算就给出升力、阻力与压力分布。SA 模型最初为航空外流设计,只多一个输运方程,工程上用得很广。与层流 N–S 相比,湍流模型带来三样东西:多一个未知量和方程;涡粘性 μt = ρν̃fv1(χ) 进入动量与能量方程的粘性通量;依赖壁面距离 d 的源项,而 d 是网格坐标的函数。图 1.2 画出 fv1 怎样把 ν̃ 变成涡粘性。

In fluid dynamics, RANS with a turbulence model is the usual way to compute steady high-Reynolds-number flows around aircraft, turbomachinery and the like: it resolves no individual eddy, only the mean flow, and one calculation gives the lift, the drag and the pressure distribution. The SA model was designed for aerodynamic external flows; it adds one transport equation and is widely used in engineering. Compared with laminar N–S the turbulence model brings three things: one more unknown and equation; the eddy viscosity μt = ρν̃fv1(χ) in the viscous fluxes of momentum and energy; and source terms depending on the wall distance d, a function of the mesh coordinates. Figure 1.2 shows how fv1 turns ν̃ into an eddy viscosity.

10⁻⁷10⁻⁶10⁻⁵10⁻⁴10⁻³10⁻²10⁻¹10⁰10¹10²10⁻¹10⁰10¹10²χ = ρν̃/μμt/μμt = μcv1 = 7.1μt/μ = χ fv1(χ)χ⁴/cv1³ (χ ≪ cv1)χ (fv1 → 1)本页收敛解的 χ:χ of this page's solution:χ ∈ [0.162, 2.42]μt/μ ≤ 0.092来流:χ∞ = 3free stream: χ∞ = 3μt/μ = 0.210
图 1.2 · SA 模型的涡粘性 μt/μ = χfv1(χ),χ = ρν̃/μ(双对数坐标)。虚线是两个极限:χ 小时 χ⁴/cv1³,fv1 把壁面附近的涡粘性压得很低;χ 大时 fv1 → 1,μt ≈ ρν̃。在 χ = cv1 处 fv1 = 1/2。圆点是来流,粗线是本页收敛解(二阶)各控制体的 χ(壁面节点上 ν̃ = 0,不计):这张教学网格的雷诺数很低,涡粘性小于分子粘度;高雷诺数边界层里离壁面稍远,χ 就远大于 cv1。Figure 1.2 · The eddy viscosity of the SA model, μt/μ = χfv1(χ) with χ = ρν̃/μ (log–log axes). The dashed lines are its two limits: χ⁴/cv1³ for small χ, where fv1 damps the eddy viscosity near walls strongly, and, for large χ, fv1 → 1 and μt ≈ ρν̃. At χ = cv1, fv1 = 1/2. The circle is the free stream, the thick line the χ of every control volume of this page's converged solution (second order; the wall nodes, where ν̃ = 0, left out): the Reynolds number of this teaching mesh is low and the eddy viscosity stays below the molecular one; in a high-Reynolds-number boundary layer χ is far above cv1 a short distance from the wall.

在本课程里,二维非结构网格上 RANS–SA 的前向与伴随是整个系列的目标。用于气动外形优化的工业伴随求解器求的正是这类方程组:一次伴随求解给出阻力这样一个目标对成百上千个外形参数的导数。前面各页一次加一样东西,本页把它们合在一起(图 1.3)。本页的前向与伴随对五个方程一起求导,涡粘性对 ν̃ 的依赖、SA 源项与壁面距离都在其中;有些工程代码冻结湍流量、只对平均流方程求伴随,本页不做这种近似。

In this course, the tangent and the adjoint of RANS–SA on a two-dimensional unstructured mesh are the goal of the whole series. Industrial adjoint solvers for aerodynamic shape optimisation solve exactly this kind of system: one adjoint solve gives the derivative of one objective, such as the drag, with respect to hundreds or thousands of shape parameters. The earlier pages add one ingredient at a time; this page puts them together (Figure 1.3). Its tangent and adjoint differentiate all five equations together, including the eddy viscosity's dependence on ν̃, the SA source and the wall distance; some production codes freeze the turbulence quantities and take the adjoint of the mean-flow equations only, and this page makes no such approximation.

图 1.3 · 从一维 Burgers 到本页的路线,与一维 Burgers 页的同一张图。每往右一步主要增加一类内容,每点的未知量从 1 个增加到 5 个(由各页的模型代码按默认设置数出);每一页都用面循环组装残差,前向与伴随沿同一个循环求导。本页在路线的终点;每个方框都链接到那一页的第 1 节(格点版本)。Figure 1.3 · The route from 1-D Burgers to this page, as in the same figure of the 1-D Burgers page. Each step to the right mainly adds one kind of ingredient, and the unknowns per point grow from 1 to 5 (counted by each page's model code at its default settings); every page assembles its residual with face loops, and the tangent and the adjoint differentiate the same loops. This page is the end of the route; every box links to Section 1 of that page (the node-centred version).

本页要回答的问题

The question this page answers

本页只回答一个问题:51 个设计变量 D 各改变一点,CD 改变多少?页首的全页路线图把后面各节串成一条线:前向每个设计变量解一次线性方程,共 51 次;伴随只解一次转置方程。

This page answers one question: how much does CD change when each of the 51 design variables D changes a little? The page roadmap at the top strings the later sections together: the tangent solves one linear system per design variable, 51 in all, the adjoint a single transposed one.

要在计算机上回答它,先要把上面的偏微分方程变成有限个未知量的代数方程 R(U) = 0。第 2 节放下网格与控制体,第 3 节再把每个控制体上的守恒写成面通量之和:Roe 通量、最小二乘重构、粘性通量与 SA 源项。

To answer it on a computer, the partial differential equations above must first become algebraic equations R(U) = 0 in finitely many unknowns. Section 2 lays out the mesh and the control volumes, and Section 3 writes conservation on each as a sum of face fluxes: the Roe flux, the least-squares reconstruction, the viscous flux and the SA source.

第 2 节Section 2

网格:对偶控制体、对偶面与壁面距离

Mesh: dual control volumes, dual faces and wall distance

第 1 节的方程在区域里每一点成立,计算机却只能存有限个数。本节决定未知量放在哪里:网格、控制体与它们的几何量,包括 SA 源项要用的壁面距离。

The equations of Section 1 hold at every point of the domain, but a computer stores finitely many numbers. This section decides where the unknowns live: the mesh, the control volumes and their geometry, including the wall distance the SA source needs.

网格与二维对流页面完全相同,编号也相同:节点逐圈从壁面向外,单元逐圈编号,面按“内部、壁面、远场”排序。未知量放在节点上:每个节点的控制体是中位对偶,由相邻单元的边中点与单元中心围成。区别在于每个控制体现在有 5 个未知量,而不是 1 个。

The mesh is exactly that of the two-dimensional advection page, with the same numbering: nodes ring by ring from the wall outwards, cells ring by ring, faces sorted interior, wall, far field. The unknowns live at the nodes: each node's control volume is its median dual, bounded by the edge midpoints and the centres of the cells around it. The difference is that every control volume now carries 5 unknowns instead of 1.

123456789101112131415161718192021222324琥珀色:壁面(无滑移、绝热) 蓝色实线:来流 蓝色虚线:出口amber: the wall (no-slip, adiabatic) · solid blue: inflow · dashed blue: outlet
图 2.1 · 与二维对流页面同一张网格:24 个节点就是 24 个控制体(中位对偶,虚线是对偶面),每个控制体 5 个未知量,共 120 个。48 条边给出 48 个内部对偶面,16 条边界边各给出两个半面(壁面 16 个、远场 16 个)。Figure 2.1 · The same mesh as the two-dimensional advection pages: the 24 nodes are the 24 control volumes (median duals; the dashed lines are the dual faces), 5 unknowns each, 120 in all. The 48 edges give 48 interior dual faces, and the 16 boundary edges two half-faces each (16 on the wall, 16 on the far field).

一个面循环要读的几何量都画在下图里。和标量页面相比多了两样:从控制体中心 xi 到面点 xf 的重构方向 xf − xi(二阶格式沿它把中心值外推到面上),与两侧中心的连线 Δx = xR − xL(粘性通量沿它取两点差分)。

The geometric quantities a face loop reads are all in the figure below. Compared with the scalar pages there are two more: the reconstruction direction xf − xi from a control-volume centre xi to the face point xf (the second-order scheme extrapolates the centre value along it), and the line Δx = xR − xL between the two centres (the viscous flux takes its two-point difference along it).

xLxRnxfΔxxf − xL、xf − xR:重构的方向xf − xL, xf − xR: the reconstruction directionsΔx = xR − xL:修正梯度的方向;n:面积加权法向Δx = xR − xL: the corrected gradient's direction; n: the area-weighted normal
图 2.2 · 对偶面 e17(紫色的两段):面循环读取的全部几何量。重构从两侧中心沿 xf − xL、xf − xR 外推到面点 xf(边中点);粘性通量沿两侧中心的连线 Δx 取两点差分;n 的长度就是面的面积(二维中是长度)。对偶面由一段或两段组成,法向取两段之和:这是 SU2 的边格式,每条边只算一次通量。Figure 2.2 · The dual face e17 (the two violet segments): every geometric quantity the face loop reads. The reconstruction extrapolates from each centre along xf − xL, xf − xR to the face point xf (the edge midpoint); the viscous flux takes its two-point difference along the line Δx between the two centres; the length of n is the face area (a length in two dimensions). A dual face has one or two segments and the normal is their sum: SU2's edge-based scheme, one flux per edge.

壁面距离

The wall distance

SA 模型的耗散项与 (ν̃/d)² 成正比,d 是到壁面的距离。本页的 di 是控制体中心到离散壁面多边形的精确欧氏距离:对每条壁面边求点到线段的距离,取最小。它是坐标的函数,所以在第 12 节的几何导数里也要求导。

The SA model's destruction term goes as (ν̃/d)², with d the distance to the wall. On this page di is the exact Euclidean distance from the control-volume centre to the discrete wall polygon: the distance from the point to each wall edge, and the smallest. It is a function of the coordinates, so the geometric derivatives of Section 12 differentiate it too.

0.490.510.630.730.720.650.590.541.391.44
图 2.3 · 壁面距离 di:每个控制体中心到壁面多边形最近点(虚线)的距离。最近点可能落在某条壁面边的内部(垂足),也可能落在顶点上;物体在这张网格上是凸八边形,到凸多边形的距离在它外部处处一阶连续可微:最近点从顶点滑进边内时,d 的导数不跳。壁面节点的 d = 0,它们的源项不计算。Figure 2.3 · The wall distance di: from each control-volume centre to the nearest point of the wall polygon (dashed). The nearest point lies inside a wall edge (a perpendicular foot) or on a vertex; the body is a convex octagon on this mesh, and the distance to a convex polygon is continuously differentiable everywhere outside it: when the nearest point slides from a vertex into an edge, the derivative of d does not jump. A wall node has d = 0 and its source is not evaluated.

逐步推导:壁面距离与它对坐标的导数

Step by step: the wall distance and its derivative with respect to the coordinates

第 12 节的几何导数要用到 ∂di/∂X。di 是分段定义的:最近点可能落在一条壁面边的内部,也可能落在顶点上。先把它写成显式公式,再逐项求导。记控制体中心为 xi,一条壁面边从壁面节点 Xa 到 Xb,e = Xb − Xa。

The geometric derivatives of Section 12 need ∂di/∂X. di is defined piecewise: the nearest point may lie inside a wall edge or at a vertex. Write it as an explicit formula first, then differentiate term by term. Let xi be the control-volume centre and let a wall edge run from the wall node Xa to Xb, with e = Xb − Xa.

第一步,直线上的最近点。直线上的点是 Xa + ξe;到 xi 的距离平方对 ξ 求导并令其为零:

Step 1, the nearest point on the line. The points of the line are Xa + ξe; differentiate the squared distance to xi with respect to ξ and set it to zero:

ddξ ∣xi−Xa−ξe∣2=−2 e⋅(xi−Xa−ξe)=0⟹ξ∗=(xi−Xa)⋅ee⋅e

第二步,截到线段上。ξ* ≤ 0 时最近点是顶点 Xa,ξ* ≥ 1 时是 Xb,否则是垂足。记截断后的参数 ξ = min(max(ξ*, 0), 1),最近点 xw = Xa + ξe,距离与它的单位方向是

Step 2, clamp to the segment. For ξ* ≤ 0 the nearest point is the vertex Xa, for ξ* ≥ 1 it is Xb, and otherwise the foot of the perpendicular. With the clamped parameter ξ = min(max(ξ*, 0), 1) the nearest point is xw = Xa + ξe, and the distance and its unit direction are

d=∣xi−xw∣,nw=xi−xwd

di 取所有壁面边中最小的那个(mesh.js 的 segDist 与 geometry 正是这样算的,分支都按实数值选)。

di is the smallest over all wall edges (mesh.js segDist and geometry compute exactly this, every branch chosen on real values).

第三步,垂足情形求导。d² = |xi − Xa − ξe|²,而 ξ = ξ*(xi, Xa, Xb) 本身也随坐标变。但 ξ* 使这个距离平方取极小,∂(d²)/∂ξ = 0:ξ 的变化对 d 没有一阶影响(包络定理)。所以只对显式出现的三个点求前向导数(图 2.4 (a)):

Step 3, differentiate in the foot case. d² = |xi − Xa − ξe|², and ξ = ξ*(xi, Xa, Xb) moves with the coordinates as well. But ξ* minimises this squared distance, so ∂(d²)/∂ξ = 0: a change of ξ has no first-order effect on d (the envelope theorem). Only the three points that appear explicitly are differentiated, in forward mode (Figure 2.4 (a)):

2d d˙=2 (xi−xw)⋅(x˙i−X˙a−ξ (X˙b−X˙a))⟹∂d∂xi=nw,∂d∂Xa=−(1−ξ) nw,∂d∂Xb=−ξ nw

nw 与 e 垂直,所以沿壁面边移动 Xa 或 Xb 不改变 d;三个导数之和为零,整体平移不改变 d。

nw is perpendicular to e, so moving Xa or Xb along the edge leaves d unchanged; the three derivatives sum to zero, and a rigid translation does not change d.

第四步,顶点情形。ξ* ≤ 0 时 d = |xi − Xa|,直接求导得 ∂d/∂xi = nw、∂d/∂Xa = −nw、∂d/∂Xb = 0:正是第三步的公式取 ξ = 0(ξ* ≥ 1 时取 ξ = 1)。一个公式覆盖两种情形;在 ξ* = 0 处两边的值与导数都相同,所以最近点从顶点滑进边内时,d 的导数不跳。

Step 4, the vertex case. For ξ* ≤ 0, d = |xi − Xa|, and direct differentiation gives ∂d/∂xi = nw, ∂d/∂Xa = −nw, ∂d/∂Xb = 0: Step 3's formula with ξ = 0 (and ξ = 1 for ξ* ≥ 1). One formula covers both cases; at ξ* = 0 both sides have the same value and the same derivative, so the derivative of d does not jump when the nearest point slides from the vertex into the edge.

第五步,回到节点坐标。格点页的中心就是节点本身,xi = Xi,所以 ∂di/∂Xi = nw;Xa、Xb 是壁面节点,各得到第三步的一项。壁面节点自己的 d = 0,不求源项,也不求导。

Step 5, back to the node coordinates. On the node page the centre is the node itself, xi = Xi, so ∂di/∂Xi = nw; Xa and Xb are wall nodes and receive the terms of Step 3. A wall node's own d = 0: it has no source and no derivative.

∂d/∂xi = nw∂d/∂Xa = −(1−ξ)nwXaXbx20xw(a) 垂足在边内:ξ = 0.04,d = 1.624(a) the foot inside the edge: ξ = 0.04, d = 1.624∂d/∂xi = nw∂d/∂Xa = −nwXaXbx9(b) 最近点是顶点:ξ* = −0.58,d = 0.494(b) the nearest point is a vertex: ξ* = −0.58, d = 0.494琥珀色:壁面多边形与最近的边 XaXb;红色箭头:d 对 xi、Xa、Xb 的导数,单位向量 nw 画成 50 像素amber: the wall polygon and the nearest edge XaXb; red arrows: ∂d/∂xi, ∂d/∂Xa, ∂d/∂Xb (nw drawn 50 px long)每个面板把壁面边放大成 150 像素;远处的中心沿虚线缩短画出(折断号),真实距离见标题each panel scales the wall edge to 150 px; a far centre is drawn closer along its dashed line (break mark)
图 2.4 · 两个控制体中心的壁面距离与它对坐标的导数(本页网格上的两个实例)。(a) 最近点是边 XaXb 上的垂足 xw:∂d/∂xi 是从 xw 指向 xi 的单位向量 nw,边的两个端点分到 −(1 − ξ)nw 与 −ξnw;三者之和为零,因为整体平移不改变 d。(b) 最近点是顶点:这个顶点分到 −nw,边的另一端为零,正是 (a) 的公式取 ξ = 0 或 1。本页 16 个求壁面距离的中心里,2 个是 (a) 的情形,14 个是 (b) 的情形。Figure 2.4 · The wall distance of two control-volume centres and its derivative with respect to the coordinates (two instances on this page's mesh). (a) The nearest point is the foot xw on the edge XaXb: ∂d/∂xi is the unit vector nw from xw to xi, and the two ends of the edge receive −(1 − ξ)nw and −ξnw; the three sum to zero, since a rigid translation does not change d. (b) The nearest point is a vertex: that vertex receives −nw and the other end of the edge nothing, which is (a)'s formula with ξ = 0 or 1. Of the 16 centres of this page that have a wall distance, 2 are case (a) and 14 case (b).

核对:本页 16 个中心里,2 个的最近点在边内,14 个在顶点上;对每个 di,第三至第五步的公式与 geometry() 的磁带反向扫描给出的 ∂di/∂X 最大相对差 4.6×10−16(本页代码在构建时计算)。

Check: of this page's 16 centres, 2 have their nearest point inside an edge and 14 at a vertex; for every di, the formulas of Steps 3 to 5 and a reverse sweep of a tape of geometry() give ∂di/∂X with a largest relative difference of 4.6×10−16 (computed by this page's code at build time).

图 2.5Figure 2.5

网格与几何量到这里就齐了。第 3 节把第 1 节的守恒律对每个控制体积分,写成穿过这些面的通量之和。

The mesh and its geometry are now complete. Section 3 integrates the conservation laws of Section 1 over each control volume and writes them as sums of fluxes through these faces.

第 3 节Section 3

面上的通量

The flux on a face

第 2 节给出了控制体和它们的面。本节把第 1 节的方程对每个控制体积分,写出每个面上的通量:Roe 通量、最小二乘重构、粘性通量,以及每个控制体的 SA 源项。

Section 2 gave the control volumes and their faces. This section integrates the equations of Section 1 over each control volume and writes the flux through each face: the Roe flux, the least-squares reconstruction, the viscous flux, and each control volume's SA source.

有限体积形式

The finite-volume form

对每个控制体积分(Ui 取控制体上的平均值),散度变成面上的通量和,每个控制体得到一个关于 t 的常微分方程(半离散形式):

Integrated over each control volume (Ui is the average over it), the divergence becomes a sum of face fluxes, and each control volume gets an ordinary differential equation in t (the semi-discrete form):

Vi dUidt+Ri(U)=0,Ri(U)=∑f∈∂Ωi± Φf−ViSi
Φf=roe(WL+,WR+,nf)−visc(W,G,f)

roe 是对流部分,visc 是粘性部分。面通量 Φf 从 L 流向 R:对 L 加、对 R 减,保证守恒。W = (ρ, u, v, T, ν̃) 是原始变量,G 是它们的最小二乘梯度,W+ 是重构到面上的状态。

roe is the convective part and visc the viscous one. The face flux Φf runs from L to R: added to L and subtracted from R, which makes the scheme conservative. W = (ρ, u, v, T, ν̃) are the primitive variables, G their least-squares gradients, and W+ the state reconstructed to the face.

定常解满足 R(U) = 0:这就是本页要解、并在之后各节求导的离散方程;时间项只在求解时出现(第 6 节)。格点页壁面节点的 ρu、ρv、ρν̃ 三行与来流节点的 ρ、ρu、ρv、ρν̃ 四行不是上面的常微分方程:它们被替换成边界条件本身(第 4 节),推进中始终精确满足 u = v = ν̃ = 0 与 ρ、u、v、ν̃ 的来流值。

The steady solution satisfies R(U) = 0: that is the discrete equation this page solves and, in the later sections, differentiates; the time term appears in the solve only (Section 6). The ρu, ρv and ρν̃ rows of a wall node and the ρ, ρu, ρv and ρν̃ rows of an inflow node are not ODEs like the one above: they are replaced by the boundary conditions themselves (Section 4), and u = v = ν̃ = 0 and the inflow values of ρ, u, v, ν̃ hold exactly throughout the marching.

每个面仍是一个一维问题:Roe 通量

Every face is still a one-dimensional problem: the Roe flux

面的两侧各有一个状态,Roe 通量把它们的差分解成五道波:两道声波(速度 q̃ ∓ c̃)、熵波、剪切波与 ν̃ 波(速度都是 q̃),每道波按它速度的绝对值加耗散:

Each side of a face carries a state, and the Roe flux splits their difference into five waves: two acoustic waves (speeds q̃ ∓ c̃), and the entropy, shear and ν̃ waves (all at speed q̃); each wave is dissipated in proportion to the size of its speed:

roe(WL,WR,n)=∣n∣[12(F(WL)+F(WR))⋅n^−12∑k=15∣Λk∣ Δk rk]

~ 表示 Roe 平均(以 √ρ 加权:ρ̃ = √(ρLρR),ũ、H̃、ν̃~ 是两侧的加权平均),c̃² = (γ − 1)(H̃ − ½|ũ|²),q̃ = ũ·n̂。Δ 表示 R 侧减 L 侧的跳跃,Δq = Δu·n̂。Λk 是第 k 道波的波速,rk 是 Roe 平均状态处通量 Jacobian 的右特征向量(分量按 ρ、ρu、ρv、ρE、ρν̃ 排列),Δk 是波强:把跳跃 ΔU 写成 ΣkΔkrk 时的系数。

The ~ marks a Roe average (weighted by √ρ: ρ̃ = √(ρLρR), and ũ, H̃, ν̃~ are the weighted averages of the two sides), c̃² = (γ − 1)(H̃ − ½|ũ|²) and q̃ = ũ·n̂. Δ is a jump, the R side minus the L side, and Δq = Δu·n̂. Λk is the speed of wave k, rk the right eigenvector of the flux Jacobian at the Roe-averaged state (components ordered ρ, ρu, ρv, ρE, ρν̃), and Δk the wave strength: the coefficient of rk when the jump ΔU is written as ΣkΔkrk.

Λ1,3=q~∓c~,Δ1,3=Δp∓ρ~c~ Δq2c~2,r1,3=(1, u~∓c~n^x, v~∓c~n^y, H~∓q~c~, ν~~)TΛ2=q~,Δ2=Δρ−Δpc~2,r2=(1, u~, v~, 12(u~2+v~2), ν~~)TΛ4,5=q~,Δ4r4=ρ~ (0, Δu−Δq n^x, Δv−Δq n^y, u~Δu+v~Δv−q~Δq, 0)T,Δ5r5=ρ~ Δν~ (0,0,0,0,1)T

两道声波(k = 1、3)、熵波(k = 2)、剪切波(k = 4)与 ν̃ 波(k = 5);后三道都以 q̃ 移动。剪切波与 ν̃ 波直接写成乘积 Δkrk。ρν̃ 作为被动标量跟着质量通量走:r1,2,3 的最后一个分量是 ν̃~,所以它的耗散是 ν̃~ 乘质量方程的耗散,再加 ν̃ 波的 |q̃|ρ̃Δν̃。残差里的特征值不做熵修正:熵修正是为了在声速点(|q̃ ± c̃| → 0)附近防止出现非物理的膨胀激波,本页 M = 0.2,处处亚声速,用不到它。代价是 |Λk|(k = 2, 4, 5)在 q̃ = 0 处不可导(第 4 节列出它离当前解多远)。

The two acoustic waves (k = 1, 3), the entropy wave (k = 2), the shear wave (k = 4) and the ν̃ wave (k = 5); the last three all move at q̃. The shear and ν̃ waves are written directly as the products Δkrk. ρν̃ rides on the mass flux as a passive scalar: the last component of r1,2,3 is ν̃~, so its dissipation is ν̃~ times the mass equation's, plus the ν̃ wave's |q̃|ρ̃Δν̃. The residual's eigenvalues carry no entropy fix: an entropy fix keeps non-physical expansion shocks from forming near sonic points (|q̃ ± c̃| → 0), and this page's flow at M = 0.2 is subsonic everywhere. The price is that |Λk| (k = 2, 4, 5) is not differentiable at q̃ = 0 (Section 4 lists how far the solution is from it).

图 3.1Figure 3.1

逐步推导:Roe 平均、波分解与 Roe 通量的线性化

Step by step: Roe averages, the wave decomposition and the linearisation of the Roe flux

第一步,Roe 平均的乘积法则。任一量 φ 的 Roe 平均是 φ̃ = (√ρLφL + √ρRφR)/(√ρL + √ρR),ρ̃ = √(ρLρR)。直接展开(用 ρR − ρL = (√ρR − √ρL)(√ρR + √ρL)):

Step 1, the product rule of Roe averages. The Roe average of any quantity φ is φ̃ = (√ρLφL + √ρRφR)/(√ρL + √ρR), and ρ̃ = √(ρLρR). Expanding directly (with ρR − ρL = (√ρR − √ρL)(√ρR + √ρL)):

φ~ Δρ+ρ~ Δφ=(ρLφL+ρRφR)(ρR−ρL)+ρLρR (φR−φL)=ρRφR−ρLφL=Δ(ρφ)

所以对 φ = u、v、H、ν̃,跳跃 Δ(ρφ) 精确地等于 φ̃Δρ + ρ̃Δφ:在 Roe 平均处把跳跃线性化没有误差。

So for φ = u, v, H, ν̃ the jump Δ(ρφ) is exactly φ̃Δρ + ρ̃Δφ: linearising the jump at the Roe average makes no error.

第二步,压力的跳跃。本页 p = ρT、ρE = ρ(cvT + ½|u|²),所以 p = (γ − 1)(ρE − ½ρ|u|²)。写 ρ|u|² = |√ρ u|²,并用 √ρLuL + √ρRuR = (√ρL + √ρR)ũ,得 ½Δ(ρ|u|²) = ũ·Δ(ρu) − ½|ũ|²Δρ,于是

Step 2, the pressure jump. On this page p = ρT and ρE = ρ(cvT + ½|u|²), so p = (γ − 1)(ρE − ½ρ|u|²). Writing ρ|u|² = |√ρ u|² and using √ρLuL + √ρRuR = (√ρL + √ρR)ũ gives ½Δ(ρ|u|²) = ũ·Δ(ρu) − ½|ũ|²Δρ, hence

Δp=(γ−1)[Δ(ρE)−u~ Δ(ρu)−v~ Δ(ρv)+12(u~2+v~2)Δρ]c~2=(γ−1)(H~−12(u~2+v~2))

第三步,求波强。把跳跃写成 ΔU = ΣkΔkrk,逐个分量比较(rk 见上式)。质量分量:Δ1 + Δ2 + Δ3 = Δρ。法向动量 n̂·Δ(ρu) = q̃Δρ + ρ̃Δq:c̃(Δ3 − Δ1) = ρ̃Δq。把第二步 Δp 的式子(γ − 1 乘方括号)作用在每个 rk 上,r1、r3 给 c̃²,r2 与剪切、ν̃ 两个向量给 0,所以 c̃²(Δ1 + Δ3) = Δp。三式联立:

Step 3, the wave strengths. Write the jump as ΔU = ΣkΔkrk and compare component by component (the rk as above). The mass component: Δ1 + Δ2 + Δ3 = Δρ. The normal momentum n̂·Δ(ρu) = q̃Δρ + ρ̃Δq: c̃(Δ3 − Δ1) = ρ̃Δq. Step 2's formula for Δp ((γ − 1) times the bracket) applied to each rk gives c̃² for r1 and r3 and 0 for r2 and the shear and ν̃ vectors, so c̃²(Δ1 + Δ3) = Δp. Together:

Δ1,3=Δp∓ρ~c~ Δq2c~2,Δ2=Δρ−Δpc~2

动量里剩下的 ρ̃(Δu − Δq n̂) 是剪切波;ρν̃ 里剩下的 ρ̃Δν̃(第一步取 φ = ν̃)是 ν̃ 波:正是上面的 Δ4r4、Δ5r5。

What remains in the momentum, ρ̃(Δu − Δq n̂), is the shear wave; what remains in ρν̃, ρ̃Δν̃ (Step 1 with φ = ν̃), is the ν̃ wave: the Δ4r4 and Δ5r5 above.

第四步,耗散矩阵。rk 是 Roe 平均状态处通量 Jacobian 的特征向量,特征值 Λk。把跳跃按特征向量展开、逐波乘 |Λk|,就是 |J̃c|ΔU。记 𝓡 = (r1, …, r5):

Step 4, the dissipation matrix. The rk are the eigenvectors of the flux Jacobian at the Roe-averaged state, with eigenvalues Λk. Expanding the jump in eigenvectors and multiplying each wave by |Λk| gives |J̃c|ΔU. With 𝓡 = (r1, …, r5):

∑k∣Λk∣ Δk rk=ℛ ∣Λ∣ ℛ−1 ΔU=∣J~c∣ ΔU,(∣J~c∣ΔU)ρν~=ν~~ (∣J~c∣ΔU)ρ+∣q~∣ ρ~ Δν~

第二式来自 r1、r2、r3 的最后一个分量都是 ν̃~、剪切波的是 0(model.js 的 d4 = st·d0 + sh·ds)。所以 |J̃c| 的 ρν̃ 列只有对角元 |q̃|:ν̃ 不进入平均流方程的耗散,而 ρν̃ 的耗散是质量耗散乘 ν̃~ 再加自己的一项。本页一个面上的 |J̃c| 见图 3.2。

The second formula holds because the last component of r1, r2 and r3 is ν̃~ and that of the shear wave is 0 (model.js's d4 = st·d0 + sh·ds). So the ρν̃ column of |J̃c| holds only the diagonal |q̃|: ν̃ does not enter the mean-flow equations' dissipation, and ρν̃'s dissipation is the mass dissipation times ν̃~ plus a term of its own. Figure 3.2 shows |J̃c| on one face of this page.

第五步,线性化。一阶格式 Φ = |n|[½(F(UL) + F(UR))·n̂ − ½|J̃c|ΔU],而 J̃c 同时依赖两侧状态,所以

Step 5, the linearisation. At first order Φ = |n|[½(F(UL) + F(UR))·n̂ − ½|J̃c|ΔU], and J̃c depends on both states, so

∂Φ∂UL=∣n∣[12Jc(UL)+12∣J~c∣−12 ∂∣J~c∣∂UL ΔU]

最后一项与跳跃 ΔU 成正比,含 |Λk| 的导数 sgn Λk(Λk = 0 处不可导,第 4 节列出了余量)。局部磁带对核的每个运算求导,三项全部精确算到;第 6 节的近似 Jacobian 只留前两项。二阶格式的面状态是 WL+ = WL + GL·(xf − xL),所以 Roe 部分对 WL 的导数等于它对 WL+ 的导数,对 GL 的导数是它再乘 (xf − xL)T;粘性通量另外直接读 WL、WR 与 GL、GR,所以面核在两种格式里都有这 30 个输入。

The last term is proportional to the jump ΔU and contains the derivative of |Λk|, sgn Λk (not differentiable at Λk = 0; Section 4 lists the margins). The local tape differentiates every operation of the kernel, so all three terms come out exactly; the approximate Jacobian of Section 6 keeps only the first two. At second order the face state is WL+ = WL + GL·(xf − xL), so the Roe part's derivative with respect to WL equals its derivative with respect to WL+, and with respect to GL it is that times (xf − xL)T; the viscous flux reads WL, WR and GL, GR directly as well, which is why the face kernel has these 30 inputs at either order.

(a) 波速 Λk 与每道波的耗散 |Λk|Δk rk(a) the speeds Λk and each wave's dissipation |Λk|Δk rkΛk‖|Λk|Δk rk‖(对数)‖|Λk|Δk rk‖ (log)声波 1acoustic 1−1.9265.8×10−1熵波entropy−0.4012.6×10−4声波 3acoustic 31.1244.1×10−1剪切波shear−0.4011.8×10−2ν̃ 波ν̃ wave−0.4011.1×10−3|q̃| = 0.4009,c̃ = 1.525:c̃/|q̃| ≈ 4|q̃| = 0.4009, c̃ = 1.525: c̃/|q̃| ≈ 4对数轴:10-4 到 100log axis: 10-4 to 100(b) 中心状态的 |J̃c|(b) |J̃c| at the centre states行:方程;列:U 的分量rows: equations; columns: U0.280.12−0.110.200−0.361.17−0.580.1500.23−0.550.73−0.070−0.531.01−0.871.580−9e−42e−3−2e−33e−30.35ρρuρvρEρν̃ρρuρvρEρν̃
图 3.2 · Roe 通量在面 e17(图 2.2 中的那个面)上。(a) 取 U* 处的二阶面状态,五道波:两道声波以 q̃ ∓ c̃ 传播,熵波、剪切波与 ν̃ 波都以 q̃ 传播;右边是每道波对耗散的贡献 |Λk|Δkrk 的大小。(b) |J̃c| = 𝓡|Λ|𝓡−1 取在两侧的中心状态上(一阶,与第 6 节近似 Jacobian P 用的相同,所以它的对角元 |q̃| 与 (a) 下的值不同),蓝为正、紫为负,深浅按绝对值:最后一列只有对角元 |q̃|,最后一行等于第一行乘 ν̃~ 再加 |q̃|(e5 − ν̃~e1)T,这就是“ρν̃ 作为被动标量跟着质量走”。Figure 3.2 · The Roe flux on face e17 (the face of Figure 2.2). (a) At the second-order face states of U*, the five waves: the two acoustic waves travel at q̃ ∓ c̃, the entropy, shear and ν̃ waves at q̃; on the right the size of each wave's share of the dissipation, |Λk|Δkrk. (b) |J̃c| = 𝓡|Λ|𝓡−1 at the two centre states (first order, as the approximate Jacobian P of Section 6 takes it, so its diagonal |q̃| differs from the value under (a)), blue positive and violet negative, shaded by size: its last column holds only the diagonal |q̃|, and its last row is the first row times ν̃~ plus |q̃|(e5 − ν̃~e1)T, which is what “ρν̃ rides on the mass flux as a passive scalar” means.

核对:本页全部 48 个内部面上(U* 处的二阶面状态),Jc(W̃)rk = Λkrk 的相对残差最大 3.2×10−16;ΣkΔkrk 重建跳跃 ΔU 到 1.2×10−14;𝓡|Λ|𝓡−1ΔU 与 model.js 的耗散相差 7.2×10−15;Roe 性质 F(UR) − F(UL) = Jc(W̃)ΔU 成立到 1.3×10−14;|J̃c| 的 ρν̃ 行与列符合第四步到 3.3×10−18。第五步被丢掉的最后一项(一阶、中心状态)占磁带给出的 ∂Φ/∂UL 的比例(Frobenius 范数):最大 32.3%,中位数 8.9%(本页代码在构建时计算)。

Check: on all 48 interior faces of this page (the second-order face states at U*), Jc(W̃)rk = Λkrk holds to a relative residual of at most 3.2×10−16; ΣkΔkrk rebuilds the jump ΔU to 1.2×10−14; 𝓡|Λ|𝓡−1ΔU agrees with model.js's dissipation to 7.2×10−15; Roe's property F(UR) − F(UL) = Jc(W̃)ΔU holds to 1.3×10−14; and the ρν̃ row and column of |J̃c| follow Step 4 to 3.3×10−18. The last term dropped in Step 5 (first order, centre states) is at most 32.3% of the taped ∂Φ/∂UL (Frobenius norm), 8.9% at the median (computed by this page's code at build time).

第二步的恒等式与第三步的分解另由 sympy 符号验证(check_enrich_sympy.py)。

The identity of Step 2 and the decomposition of Step 3 are also verified symbolically by sympy (check_enrich_sympy.py).

最小二乘重构:一阶与二阶

Least-squares reconstruction: first and second order

每个控制体的梯度来自无权最小二乘:

Each control volume's gradient comes from unweighted least squares:

Gi=(∑jΔxij ΔxijT)−1∑jΔxij (Wj−Wi),Δxij=xj−xi

模板是边相邻的节点。壁面节点本身就是未知量(强条件下 u = v = ν̃ = 0),所以不需要额外的壁面点。二阶格式把中心值沿 xf − xi 外推:W+ = Wi + Gi·(xf − xi),不加限制器(流动无激波);一阶格式直接取 W+ = Wi。粘性通量与 SA 源项在两种格式里都用这些梯度,所以一阶/二阶开关只改变对流通量。

The stencil is the edge neighbours. A wall node is itself an unknown (u = v = ν̃ = 0 under the strong condition), so no extra wall point is needed. The second-order scheme extrapolates the centre value along xf − xi: W+ = Wi + Gi·(xf − xi), without a limiter (the flow has no shocks); the first-order scheme takes W+ = Wi. The viscous flux and the SA source use these gradients in both schemes, so the first/second-order switch changes the convective flux only.

逐步推导:最小二乘梯度、它的权重与转置

Step by step: the least-squares gradient, its weights and its transpose

第一步,拟合问题。在中心 xi 附近用线性函数 Wi + G·(x − xi) 拟合模板点上的值,取使误差平方和最小的 G(W 的每个分量分别做):

Step 1, the fitting problem. Near the centre xi, fit the values at the stencil points by the linear function Wi + G·(x − xi), and take the G that minimises the sum of squared misfits (for each component of W separately):

Gi=arg min⁡G ∑j(Wi+G⋅Δxij−Wj)2,Δxij=xj−xi

第二步,法方程。对 G 求梯度并令其为零:

Step 2, the normal equations. Set the gradient with respect to G to zero:

∑j2 Δxij(G⋅Δxij−(Wj−Wi))=0⟹𝒩i Gi=∑jΔxij (Wj−Wi),𝒩i=∑jΔxijΔxijT

𝒩i 是 2×2 对称矩阵;只要模板点不全在一条过 xi 的直线上,它就正定。

𝒩i is a symmetric 2×2 matrix, positive definite as long as the stencil points do not all lie on one line through xi.

第三步,显式的权重。2×2 矩阵的逆直接写出(mesh.js 的 weights 正是这几行):

Step 3, explicit weights. The inverse of a 2×2 matrix written out (mesh.js's weights are exactly these lines):

𝒩i−1=1𝒩xx𝒩yy−𝒩xy2(𝒩yy−𝒩xy−𝒩xy𝒩xx),Γij=𝒩i−1Δxij,Gi=∑jΓij (Wj−Wi)

权重 Γij 只依赖几何,与 W 无关:梯度那一遍是线性算子 Γ,Γij 就是它的元素。

The weights Γij depend on the geometry only, not on W: the gradient pass is the linear operator Γ, and the Γij are its entries.

第四步,线性场精确。若 W 是线性场,Wj − Wi = Δxij·∇W 对所有 j 成立,则

Step 4, exact for linear fields. If W is linear, Wj − Wi = Δxij·∇W for every j, and then

Gi=𝒩i−1∑jΔxij ΔxijT ∇W=∇W⟺∑jΓij ΔxijT=I

每个节点的一组权重都满足它,壁面节点也一样(它们的 u、v、ν̃ 本身就是未知量)。

Every node's weight set satisfies it, the wall nodes' too (their u, v, ν̃ are unknowns themselves).

第五步,前向与转置。Γ 是线性的,前向就是同一组权重作用在 W˙ 上;伴随把它转置,梯度 Gi 的伴随 Gˉi 按累加送回整个模板:

Step 5, the tangent and the transpose. Γ is linear, so the tangent applies the same weights to W˙; the adjoint transposes it, and the adjoint Gˉi of the gradient Gi goes back over the whole stencil as accumulations:

G˙i=∑jΓij (W˙j−W˙i)⟺Wˉj+=Γij⋅Gˉi,Wˉi–=Γij⋅Gˉi

两者是同一个双线性型 ∑iGˉi⋅∑jΓij(W˙j−W˙i) 按两种次序求和(core.js applyAT 的 “pass 1 reversed”);两个方向画在图 3.3 (b) 里。

Both are the same bilinear form ∑iGˉi⋅∑jΓij(W˙j−W˙i), summed in two orders (core.js applyAT's “pass 1 reversed”); both directions are drawn in Figure 3.3 (b).

第六步,对坐标的前向导数(第 12 节用)。Δxij 随中心移动,Δx˙ij=x˙j−x˙i;由 (𝒩−1)⋅=−𝒩−1𝒩˙𝒩−1,

Step 6, the forward derivative with respect to the coordinates (used in Section 12). Δxij moves with the centres, Δx˙ij=x˙j−x˙i; with (𝒩−1)⋅=−𝒩−1𝒩˙𝒩−1,

Γ˙ij=𝒩i−1(Δx˙ij−𝒩˙i Γij),𝒩˙i=∑k(Δx˙ik ΔxikT+Δxik Δx˙ikT)
x1x10x16x17x18x9(a) 模板与权重 Γij = 𝒩i−1Δxij(a) the stencil and the weights Γij = 𝒩i−1Δxij(b) 前向收集,伴随分发(b) the tangent gathers, the adjoint scatters绿色:前向 ˙Gi = Σj Γij(˙Wj − ˙Wi) 红色:伴随 ¯Wj += Γij·¯Gi,¯Wi −= Γij·¯Gigreen: tangent ˙Gi = Σj Γij(˙Wj − ˙Wi) · red: adjoint ¯Wj += Γij·¯Gi, ¯Wi −= Γij·¯Gi箭头长度按 |Γij| 缩放;灰色虚线是 Δxijarrows scaled by |Γij|; grey dashed: Δxij
图 3.3 · 节点 9 的最小二乘模板:5 个边相邻的节点。(a) 权重 Γij = 𝒩i−1Δxij(绿色箭头)一般不与 Δxij 平行:𝒩i−1 把稀疏方向上的点加重。(b) 同一组权重的两种用法:前向里梯度从模板收集(绿色,指向 x9),伴随里梯度的权重送回模板(红色,从 x9 出发),自己的那一项取负。Figure 3.3 · The least-squares stencil of node 9: its 5 edge neighbours. (a) The weights Γij = 𝒩i−1Δxij (green arrows) are in general not parallel to Δxij: 𝒩i−1 weights up the points in the sparsely sampled directions. (b) Two uses of the same weights: in the tangent the gradient gathers from its stencil (green, towards x9), in the adjoint the gradient's weight is sent back over the stencil (red, from x9), minus the sum at its own point.

核对:本页 24 组权重(邻居个数:8 个控制体有 3 个、8 个控制体有 4 个、8 个控制体有 5 个):第三步的 Γij 与 mesh.js 算出的权重最大相对差 0;ΣjΓijΔxijT 与 I 相差 2.2×10−16;一个线性场的梯度误差 3.3×10−16;沿一个随机坐标方向,第六步的 Γ˙ij 与几何磁带的前向扫描相差 5.2×10−15;随机向量上 ⟨Gˉ,ΓW˙⟩ 与 ⟨ΓTGˉ,W˙⟩ 相差 3.8×10−16(本页代码在构建时计算)。

Check: this page's 24 weight sets (neighbours: 8 control volumes have 3, 8 control volumes have 4, 8 control volumes have 5): the Γij of Step 3 and mesh.js's weights differ by at most 0; ΣjΓijΔxijT differs from I by 2.2×10−16; a linear field's gradient is off by 3.3×10−16; along a random coordinate direction, Step 6's Γ˙ij and a forward sweep of the geometry's tape differ by 5.2×10−15; and on random vectors ⟨Gˉ,ΓW˙⟩ and ⟨ΓTGˉ,W˙⟩ differ by 3.8×10−16 (computed by this page's code at build time).

粘性通量:边上的修正平均梯度

The viscous flux: the corrected average gradient on the edge

LR∇φavg(φR − φL)/|Δx|∇φavg = ½(GL + GR):两侧最小二乘梯度的平均∇φavg = ½(GL + GR): the mean of the two gradients沿 Δx 的分量 (∇φavg·Δx)/|Δx| 被换成its component along Δx, (∇φavg·Δx)/|Δx|, is replaced by两点差分 (φR − φL)/|Δx|the two-point difference (φR − φL)/|Δx|∇fφ = ∇φavg − (∇φavg·Δx − (φR − φL)) Δx / |Δx|²∇fφ = ∇φavg − (∇φavg·Δx − (φR − φL)) Δx / |Δx|²Δx 方向上只剩两个中心值:不会出现棋盘模式along Δx only the two centre values remain: no checkerboard
图 3.4 · 粘性通量在边上用 SU2 的修正平均梯度(CAvgGrad):平均梯度 ∇φavg 提供与 Δx 垂直的部分,沿 Δx(两侧中心的连线 xR − xL)的部分换成两个中心值的差分。W 的四个分量 u、v、T、ν̃ 各自这样处理;系数(μ、μt、ρa)取两侧平均。红色箭头是替换后沿 Δx 的分量 (φR − φL)/|Δx|(示意)。Figure 3.4 · The viscous flux uses SU2's corrected average gradient on the edge (CAvgGrad): the averaged gradient ∇φavg supplies the part across Δx, and the part along Δx (the line xR − xL between the two centres) becomes the difference of the two centre values. Each of the four components u, v, T and ν̃ of W is treated so; the coefficients (μ, μt, ρa) are the averages of the two sides. The red arrow is the component along Δx after the replacement, (φR − φL)/|Δx| (schematic).

逐步推导:修正平均梯度与粘性通量的线性化

Step by step: the corrected average gradient and the linearisation of the viscous flux

第一步,拆开平均梯度。对 u、v、T、ν̃ 中的某个分量 φ,记两侧最小二乘梯度的平均为 ∇φavg = ½(GL + GR),Δx = xR − xL,单位向量 Δx̂ = Δx/|Δx|。把平均梯度拆成沿 Δx 与垂直于 Δx 的两部分:

Step 1, split the average gradient. For one component φ of u, v, T, ν̃, let ∇φavg = ½(GL + GR) be the mean of the two least-squares gradients, Δx = xR − xL, and Δx̂ = Δx/|Δx| its unit vector. Split the mean into its parts along and across Δx:

∇φavg=(∇φavg⋅Δx^) Δx^+(I−Δx^ Δx^T)∇φavg

第二步,替换沿 Δx 的部分。沿 Δx 的方向导数改用两个中心值的差 (φR − φL)/|Δx|,得到面上的梯度 ∇fφ(model.js 的 corrected()):

Step 2, replace the part along Δx. The directional derivative along Δx is replaced by the difference of the two centre values, (φR − φL)/|Δx|, which gives the face gradient ∇fφ (model.js corrected()):

∇ ⁣fφ=(I−Δx^ Δx^T)∇φavg+φR−φL∣Δx∣ Δx^=∇φavg−(∇φavg⋅Δx−(φR−φL))Δx∣Δx∣2

第三步,面梯度的导数。∇fφ 对它的四个输入都是线性的:

Step 3, the derivatives of the face gradient. ∇fφ is linear in each of its four inputs:

∂∇ ⁣fφ∂φR=−∂∇ ⁣fφ∂φL=Δx∣Δx∣2,∂∇ ⁣fφ∂GL=∂∇ ⁣fφ∂GR=12(I−Δx^ Δx^T)

两侧的梯度只经过“垂直于 Δx 的投影”进入;沿 Δx 只剩两点差,所以不会出现棋盘模式。

The two gradients enter only through the projection across Δx; along Δx only the two-point difference remains, so no checkerboard mode appears.

第四步,通量与系数。面上的粘性通量(第 1 节的 Fv·n)读四个面梯度与两侧平均的系数:

Step 4, the flux and its coefficients. The face's viscous flux (Section 1's Fv·n) reads the four face gradients and coefficients averaged over the two sides:

τn=μe[(∇ ⁣f𝐮+∇ ⁣f𝐮T)n−23tr⁡(∇ ⁣f𝐮) n]Fv ⁣⋅n=(0, τn, 𝐮avg⋅τn+ke ∇ ⁣fT⋅n, ρa ∇ ⁣fν~⋅n)
μe=12(μL+μR)+12(μt,L+μt,R),𝐮avg=12(𝐮L+𝐮R)ke=cp(μavgPr+μtavgPrt),ρa=μavg+12(ρLν~L+ρRν~R)σ

这里 ∇fu 是以 ∇fu、∇fv 为行的 2×2 矩阵,uavg、μavg、μtavg 是两侧的平均(与第一步的 ∇φavg 同一个写法)。

Here ∇fu is the 2×2 matrix with rows ∇fu and ∇fv, and uavg, μavg, μtavg are the averages of the two sides (written like Step 1's ∇φavg).

第五步,系数的导数。Sutherland 律 μ = μref·1.4T1.5/(T + 0.4) 给 μT = dμ/dT = μ(1.5/T − 1/(T + 0.4));μt = ρν̃fv1(χ),χ = ρν̃/μ,fv1′ = 3cv1³χ²/(χ³ + cv1³)²,于是(其余原始变量固定)

Step 5, the derivatives of the coefficients. Sutherland's law μ = μref·1.4T1.5/(T + 0.4) gives μT = dμ/dT = μ(1.5/T − 1/(T + 0.4)); μt = ρν̃fv1(χ) with χ = ρν̃/μ and fv1′ = 3cv1³χ²/(χ³ + cv1³)², so (the other primitives held)

∂μt∂ρ=ν~ (fv1+χfv1′),∂μt∂ν~=ρ (fv1+χfv1′),∂μt∂T=−ρν~ χfv1′ μTμ

第六步,链式法则(前向模式)。τn 对 μe 与四个面梯度都是线性的;面梯度 ∇f 对它的四个输入也是线性的,作用在带点的输入上就是它的前向导数(第三步),法向 n 固定。所以

Step 6, the chain rule (forward mode). τn is linear in μe and in the four face gradients; the face gradient ∇f is linear in its four inputs as well, so applied to the dotted inputs it is its own forward derivative (Step 3), with the normal n held. So

τ˙ n=μ˙eμe τn+μe[(∇ ⁣f𝐮˙+∇ ⁣f𝐮˙T)n−23tr⁡(∇ ⁣f𝐮˙)n]μ˙e=12∑L,R(μT T˙+∂μt∂ρρ˙+∂μt∂TT˙+∂μt∂ν~ν~˙)

能量与 ν̃ 两行同理,按乘积法则逐项加点:

The energy and ν̃ rows follow the same way, a dot on each factor in turn by the product rule:

(𝐮avg ⁣⋅τn+ke∇ ⁣fT⋅n)⋅=𝐮˙avg ⁣⋅τn+𝐮avg ⁣⋅τ˙ n+k˙e∇ ⁣fT⋅n+ke∇ ⁣fT˙⋅n,(ρa ∇ ⁣fν~⋅n)⋅=(ρa)⋅ ∇ ⁣fν~⋅n+ρa ∇ ⁣fν~˙⋅n

局部磁带记下的正是这些乘积:面核对 WL、WR 的导数含系数与两点差两部分,对 GL、GR 的导数只含第三步的投影。

These products are exactly what the local tape records: the face kernel's derivative with respect to WL, WR has a coefficient part and a two-point part, and with respect to GL, GR only Step 3's projection.

核对:本页每个内部面上,corrected() 的磁带导数与第三步的公式相差 2.2×10−16;每个控制体上,viscosity() 与 eddy() 的磁带给出的 μT 与第五步三个偏导数与公式相差 7.2×10−16(本页代码在构建时计算)。

Check: on every interior face of this page, the taped derivatives of corrected() and Step 3's formulas differ by 2.2×10−16; in every control volume, μT and the three partials of Step 5 from the tapes of viscosity() and eddy() differ from the formulas by 7.2×10−16 (computed by this page's code at build time).

SA 源项

The SA source

源项是每个控制体一个点的积分:Vi 乘以中心处的 S5。它读三样东西:中心的 W、最小二乘梯度 G(涡量、∇ν̃、∇ρ)、壁面距离 d。

The source is a one-point integral per control volume: Vi times S5 at the centre. It reads three things: the centre's W, the least-squares gradients G (the vorticity, ∇ν̃, ∇ρ), and the wall distance d.

Wi = (ρ,u,v,T,ν̃)Gi = ∇Wdi(壁面距离)di (wall distance)χ = ρν̃/μ(T)Ω = |ω|B = ν̃ fv2/(κ²d²)S̃(两个分支)S̃ (two branches)r = min(·, 10)fw(r)生成项production耗散项destructioncb2 项、∇ρ·∇ν̃ 项cb2, ∇ρ·∇ν̃ terms
图 3.5 · 一个控制体的 SA 源项读什么:中心值 Wi、最小二乘梯度 Gi(涡量 ω 与 ∇ν̃、∇ρ)、壁面距离 di。三处分支都按实数值选择:S̃ 的两个分支、r 的截断、|ω| 的符号。模型函数只在控制体中心求值,所以重构到面上的 ν̃ 即使为负也无妨(它只线性地进入 Roe 通量)。Figure 3.5 · What the SA source of one control volume reads: the centre values Wi, the least-squares gradients Gi (the vorticity ω, ∇ν̃ and ∇ρ), and the wall distance di. Three branches, each chosen on real values: the two branches of S̃, the cap on r, and the sign of ω. The model functions are evaluated at control-volume centres only, so a negative ν̃ reconstructed to a face does no harm (it enters the Roe flux linearly).

逐步推导:SA 源项对 W、G 与 d 的导数

Step by step: the derivatives of the SA source with respect to W, G and d

源项核的局部 Jacobian Js(15 个输入、1 个输出;第 12 节还要它对壁面距离 d 的导数)由局部磁带求出。这里把磁带做的事按前向模式一层一层写出来:每一层给出它的点。控制体 i 的源项进入残差的 ρν̃ 行:

The source kernel's local Jacobian Js (15 inputs and 1 output; Section 12 also needs its derivative with respect to the wall distance d) comes from the local tape. Here is what the tape does in forward mode, layer by layer: each layer gives its dot. The source of control volume i enters the residual's ρν̃ row:

Ri,ρν~←Ri,ρν~+Vi si,s=a ∇ρ⋅∇ν~−ρ b ∣∇ν~∣2−ρ Q,a=ν+ν~σ,b=cb2σ
Q=cb1(1−ft2) S~ ν~−(cw1fw−cb1κ2ft2)(ν~d)2

Q 是第 1 节 S5 方括号里的净源项,s = −S5。输入是中心值 Wi = (ρ, u, v, T, ν̃)、梯度 Gi(10 个分量)与 di。

Q is the net source inside the bracket of Section 1's S5, and s = −S5. The inputs are the centre values Wi = (ρ, u, v, T, ν̃), the gradients Gi (10 entries) and di.

第一步,分子粘性。ν = μ/ρ,μ(T) 是 Sutherland 律:

Step 1, the molecular viscosity. ν = μ/ρ, and μ(T) is Sutherland's law:

μT=dμdT=μ(1.5T−1T+0.4),∂ν∂ρ=−νρ,∂ν∂T=μTρ

第二步,χ = ν̃/ν = ρν̃/μ:

Step 2, χ = ν̃/ν = ρν̃/μ:

∂χ∂ν~=1ν,∂χ∂ρ=χρ,∂χ∂T=−χ μTμ

第三步,三个阻尼函数只依赖 χ(fv2′ 用商的求导法则,1 + χfv1 − χ(fv1 + χfv1′) = 1 − χ²fv1′):

Step 3, the three damping functions depend on χ only (fv2′ by the quotient rule, with 1 + χfv1 − χ(fv1 + χfv1′) = 1 − χ²fv1′):

fv1′=3cv13χ2(χ3+cv13)2,fv2′=χ2fv1′−1(1+χfv1)2,ft2′=−2ct4 χ ft2

第四步,B = ν̃fv2/(κ²d²)。ν̃ 既直接出现,又经 χ 出现,而 ν̃·∂χ/∂ν̃ = χ;ρ 与 T 只经 χ 进入:

Step 4, B = ν̃fv2/(κ²d²). ν̃ appears directly and through χ, with ν̃·∂χ/∂ν̃ = χ; ρ and T enter through χ only:

∂B∂ν~=fv2+χfv2′κ2d2,∂B∂z=ν~fv2′κ2d2 ∂χ∂z  (z=ρ,T),∂B∂d=−2Bd

第五步,涡量。ω = ∂v/∂x − ∂u/∂y 取自最小二乘梯度 Gi,Ω = |ω|:

Step 5, the vorticity. ω = ∂v/∂x − ∂u/∂y comes from the least-squares gradients Gi, and Ω = |ω|:

∂Ω∂(∂v/∂x)=sgn⁡ω,∂Ω∂(∂u/∂y)=−sgn⁡ω

第六步,S̃ 的两支。第一支 S̃ = Ω + B:FB = ∂S̃/∂B = 1,FΩ = ∂S̃/∂Ω = 1。第二支 S̃ = Ω + Ω(c2²Ω + c3B)/Ξ,Ξ = (c3 − 2c2)Ω − B,用商的求导法则:

Step 6, the two branches of S̃. First branch, S̃ = Ω + B: FB = ∂S̃/∂B = 1 and FΩ = ∂S̃/∂Ω = 1. Second branch, S̃ = Ω + Ω(c2²Ω + c3B)/Ξ with Ξ = (c3 − 2c2)Ω − B, by the quotient rule:

FB=(c3−c2)2 Ω2Ξ2,FΩ=1+(2c22Ω+c3B) Ξ−(c3−2c2) Ω (c22Ω+c3B)Ξ2

在接缝 B = −c2Ω 处 Ξ = (c3 − c2)Ω,第二支的分式等于 −c2Ω:两支的值都是 (1 − c2)Ω,FB 与 FΩ 也都等于 1,所以 S̃ 在接缝处一阶连续。于是 S~˙=FBB˙+FΩΩ˙。本页求源项的 11 个控制体里,第二支在 0 个上起作用。

At the seam B = −c2Ω, Ξ = (c3 − c2)Ω and the second branch's fraction equals −c2Ω: both branches give (1 − c2)Ω, and FB and FΩ both equal 1, so S̃ is continuously differentiable across the seam. Hence S~˙=FBB˙+FΩΩ˙. Of this page's 11 control volumes, the second branch is active in 0.

第七步,r 与截断。r0 = ν̃/(κ²d²S̃);未截断时

Step 7, r and its cap. r0 = ν̃/(κ²d²S̃); uncapped,

r˙=1κ2d2S~(ν~˙−ν~S~ S~˙−2ν~d d˙)

截断时 r = 10 是常数,r˙=0:那里 fw 对任何输入都没有导数。本页 1 个控制体被截断。

When capped, r = 10 is a constant and r˙=0: there fw has no derivative with respect to any input. On this page 1 control volumes are capped.

第八步,g 与 fw。对 fw = g(1 + cw3⁶)1/6(g⁶ + cw3⁶)−1/6 求导,(g⁶ + cw3⁶)−1/6 − g⁶(g⁶ + cw3⁶)−7/6 = cw3⁶(g⁶ + cw3⁶)−7/6:

Step 8, g and fw. Differentiating fw = g(1 + cw3⁶)1/6(g⁶ + cw3⁶)−1/6, with (g⁶ + cw3⁶)−1/6 − g⁶(g⁶ + cw3⁶)−7/6 = cw3⁶(g⁶ + cw3⁶)−7/6:

dgdr=1−cw2+6cw2 r5,dfwdg=(1+cw36g6+cw36)1/6cw36g6+cw36,f˙w=dfwdg dgdr r˙

第九步,净源项。把以上各层代进 Q(f˙t2=ft2′χ˙):

Step 9, the net source. Put the layers above into Q (f˙t2=ft2′χ˙):

Q˙=cb1[(1−ft2)(ν~ S~˙+S~ ν~˙)−ν~S~ f˙t2]−(ν~d)2(cw1 f˙w−cb1κ2 f˙t2)−(cw1fw−cb1κ2ft2) 2ν~d(ν~˙d−ν~ d˙d2)

第十步,守恒形式的两项。密度梯度项 a∇ρ·∇ν̃ 与 cb2 项 ρb|∇ν̃|² 的导数直接写出:

Step 10, the two terms of the conservative form. The derivatives of the density-gradient term a∇ρ·∇ν̃ and the cb2 term ρb|∇ν̃|² written directly:

∂(a∇ρ⋅∇ν~)∂∇ρ=a∇ν~,∂(a∇ρ⋅∇ν~)∂∇ν~=a∇ρ,∂(a∇ρ⋅∇ν~)∂(ρ, T, ν~)=∇ρ⋅∇ν~σ(−νρ, μTρ, 1)∂(ρb∣∇ν~∣2)∂ρ=b∣∇ν~∣2,∂(ρb∣∇ν~∣2)∂∇ν~=2ρb ∇ν~

第十一步,装配 Js。s 对每个输入的导数是以上各项之和,其中 −ρQ 对 ρ 的导数是 −Q − ρ∂Q/∂ρ;乘以 Vi 就是 Js 的一行。16 个输入里有 10 个出现:ρ、T、ν̃、∇ρ 的两个分量、∂u/∂y、∂v/∂x、∇ν̃ 的两个分量与 d;u、v、∂u/∂x、∂v/∂y 与 ∇T 的导数恒为零。各部分在本页的大小见图 3.6。

Step 11, assemble Js. The derivative of s with respect to each input is the sum of the terms above, where −ρQ contributes −Q − ρ∂Q/∂ρ to the ρ entry; times Vi it is the row Js. 10 of the 16 inputs appear: ρ, T, ν̃, the two components of ∇ρ, ∂u/∂y, ∂v/∂x, the two components of ∇ν̃, and d; the derivatives with respect to u, v, ∂u/∂x, ∂v/∂y and ∇T are identically zero. Figure 3.6 shows how large each part is on this page.

10−610−510−410−310−210−10.00.20.40.60.81.01.21.4壁面距离 diwall distance di|各项|(每单位体积,S5 里的符号见图例)|term| (per unit volume; the sign in S5 as in the legend)生成productionρcb1(1 − ft2)S̃ν̃耗散destruction−ρ(cw1fw − cb1ft2/κ²)(ν̃/d)²cb2 项cb2 termρ(cb2/σ)|∇ν̃|²密度梯度项density-gradient term−a∇ρ·∇ν̃实心:增大 ν̃(S5 里为正)filled: raises ν̃ (positive in S5)空心:减小 ν̃(S5 里为负)open: lowers ν̃ (negative in S5)
图 3.6 · U* 处每个求源项的控制体(11 个)上 S5 的四个部分,横轴是壁面距离。本页 Re 很低,χ = ρν̃/μ 在 0.16 到 0.99 之间:11 个控制体里有 9 个耗散项比生成项大;χ < 0.604 时 ft2 > 1,生成项变号(空心圆,4 个)。cb2 项与密度梯度项也都在:导数要精确,就要对每一项求导。Figure 3.6 · The four parts of S5 at U* in every control volume where the source is evaluated (11 of them), against the wall distance. This page's Reynolds number is low, and χ = ρν̃/μ lies between 0.16 and 0.99: in 9 of the 11 control volumes destruction is larger than production; for χ < 0.604, ft2 > 1 and production changes sign (open circles, 4 of them). The cb2 term and the density-gradient term are present too: an exact derivative differentiates every term.

核对:把上面十一步照写成代码(enrich_data.js 的 saHand,不调用 model.js 的源项),在 U* 的每个求源项的控制体(11 个)上与 model.js source() 的磁带比较:16 个导数的最大相对差 4.9×10−15,源项值 2.8×10−15。其中第二支 0 个、r 截断 1 个、生成项为负(ft2 > 1)4 个(本页代码在构建时计算)。

Check: the eleven steps written out as code (enrich_data.js saHand, which does not call model.js's source) and the tape of model.js source() compared in every control volume where the source is evaluated (11 of them) at U*: the 16 derivatives differ by at most 4.9×10−15 (relative), the source's value by 2.8×10−15. Among them 0 are on the second branch, 1 capped, and 4 have negative production (ft2 > 1) (computed by this page's code at build time).

第三、六、七、八步的公式与接缝处的一阶连续另由 sympy 符号验证(check_enrich_sympy.py)。

The formulas of Steps 3, 6, 7 and 8 and the continuity at the seam are also verified symbolically by sympy (check_enrich_sympy.py).

到这里,内部面已经完整:两侧都有控制体,面循环读两侧的状态与梯度。边界上的面只有一侧;物面、来流与出口的条件怎样写进通量、又替换哪些行,是第 4 节的内容。

Interior faces are now complete: they have a control volume on each side, and the face loop reads the states and gradients of both. A boundary face has one side only; how the conditions of the wall, the inflow and the outlet enter its flux, and which rows they replace, is the subject of Section 4.

第 4 节Section 4

边界条件

Boundary conditions

内圈:强条件的无滑移绝热壁

Inner ring: the no-slip adiabatic wall, strongly

壁面节点的控制体the wall node's control volume(半个对偶体)(half a dual cell)节点:强条件node: strong condition替换三行:Rρu = ρu,Rρv = ρv,Rρν̃ = ρν̃three rows replaced: Rρu = ρu, Rρv = ρv, Rρν̃ = ρν̃连续与能量方程保留:经内部对偶面平衡continuity and energy kept: balanced through the interior dual faces
图 4.1 · 格点页的壁面:未知量就在壁面上。壁面节点的控制体是半个对偶体,边界的一部分是它的壁面半面;强条件替换它的三行,连续与能量方程仍经内部对偶面平衡。Figure 4.1 · The wall on the node page: the unknowns sit on the wall. A wall node's control volume is half a dual cell, bounded in part by its wall half-faces; the strong condition replaces three of its rows, and continuity and energy still balance through the interior dual faces.

壁面节点的 ρu、ρv、ρν̃ 三行在所有循环之后被替换成 U 本身,于是解满足 u = v = ν̃ = 0。连续方程与能量方程不能替换,它们仍是通量平衡。壁面半面对它们没有贡献:质量通量 ρu·n = 0,能量通量为零(绝热,且应力不做功),所以面循环跳过壁面半面。

The ρu, ρv and ρν̃ rows of a wall node are replaced by U itself after all the loops, so the solution satisfies u = v = ν̃ = 0. The continuity and energy equations cannot be replaced; they remain flux balances. The wall half-faces add nothing to them: the mass flux ρu·n = 0 and the energy flux is zero (adiabatic, and the stress does no work), so the face loop skips the wall half-faces.

外圈:远场

Outer ring: the far field

u∞, α来流inflow出口outlet来流面(u∞·n < 0):五个条件inflow faces (u∞·n < 0): five conditionsρ = 1, u = U∞cos α, v = U∞sin αν̃ = 3ν∞;T 自由,热流 qn = −ke ∂T/∂n = 0ν̃ = 3ν∞; T free, heat flux qn = −ke ∂T/∂n = 0出口面(u∞·n > 0):四个条件outlet faces (u∞·n > 0): four conditionsp n − τ·n = p∞ n (p∞ = 1)qn = 0,ν̃ 的扩散通量 ρa ∂ν̃/∂n = 0qn = 0, the ν̃ diffusive flux ρa ∂ν̃/∂n = 0两个交界点:条件的类型在这里改变the two junctions, where the kind of condition changes哪一面是来流、哪一面是出口,由 u∞·n 的符号在建网格时定下,不随解改变。Which faces are inflow and which are outlet is fixed by the sign of u∞·n when the mesh is built, never by the solution.
图 4.2 · 远场分成两部分,条件的个数由边界上进出的波决定。亚声速来流边界上,无粘极限里有四道波从外面进来(熵波、剪切波、一道声波,再加随流体走的 ν̃),只有一道声波从区域里出去,所以最多给四个值;粘性流还要一个关于热流的条件,共五个。本页给 ρ、u、v、ν̃ 四个值,T 自由、热流为零。若 T 也给定,p = ρT 就被固定,比无粘极限允许的多一个值:出去的那道声波在边界上撞上固定的压力,粘性解只能靠一层宽约 ν/c 的边界层去满足它,网格分辨不了这么薄的层。亚声速出口上只有一道声波从外面进来,无粘极限只允许给一个值(压力);粘性流要四个条件,本页给的全是通量:总牵引力 p n − τ·n 等于 p∞n(两个分量)、热流为零、ν̃ 的扩散通量为零,无粘极限里它们只剩 p = p∞。在出口上多给一个值(例如把速度也固定),同样会在出口出现一层宽约 ν/|u·n| 的数值边界层。Figure 4.2 · The far field has two parts, and the number of conditions on each is set by the waves that cross it. At a subsonic inflow, in the inviscid limit four waves come in from outside (the entropy wave, the shear wave, one acoustic wave, and ν̃ carried with the fluid) and one acoustic wave leaves, so at most four values can be given; a viscous flow needs one more condition, on the heat flux, five in all. This page gives ρ, u, v and ν̃, and leaves T free with zero heat flux. Fixing T as well would fix p = ρT, one value more than the inviscid limit allows: the outgoing acoustic wave meets a fixed pressure at the boundary, and the viscous solution can satisfy it only through a layer of width about ν/c, far too thin for any mesh here. At a subsonic outlet one acoustic wave comes in, so the inviscid limit allows one value (the pressure); the viscous flow needs four conditions, and this page gives fluxes only: the total traction p n − τ·n equals p∞n (two components), the heat flux is zero, and the ν̃ diffusive flux is zero, which in the inviscid limit leave p = p∞ alone. Giving one more value at the outlet (fixing the velocity too, say) produces a numerical layer of width about ν/|u·n| there in the same way.

来流节点的 ρ、ρu、ρv、ρν̃ 四行在循环之后替换成 U − U∞(强条件);能量行保留,来流半面上的通量是本节点状态的对流通量减去本节点梯度给出的粘性通量,没有热流。出口半面:本节点的状态,压力换成 p∞ = 1,没有粘性通量。一个节点只要有一个来流半面就是来流节点,所以两个交界节点也是来流节点,它们的出口半面只进入能量行。

The ρ, ρu, ρv and ρν̃ rows of an inflow node are replaced by U − U∞ after the loops (a strong condition); the energy row stays, and the flux through an inflow half-face is the node state's convective flux minus the viscous flux of the node's gradients, with no heat flux. An outlet half-face: the node's own state with its pressure replaced by p∞ = 1, and nothing viscous. A node with one inflow half-face is an inflow node, so the two junction nodes are inflow nodes too, and their outlet half-faces enter their energy rows only.

在解处冻结的分支

The branches, frozen at the solution

离散残差里有几处不可导点。导数(前向、伴随、复数步长)都在当前解所在的那一侧分支上取;只要解离分支点足够远,差分的步长就跨不过去。下表列出二阶格式在收敛解处的距离:

The discrete residual has a few points where it is not differentiable. Every derivative (tangent, adjoint, complex step) is taken on the branch the solution sits on; as long as the solution is far enough from a switch, a finite-difference step cannot cross it. The table lists the distances at the converged second-order solution:

分支branch当前解处的余量margin at the solution
Ω = |ω| 在 ω = 0Ω = |ω| at ω = 0min|ω| / max|ω| = 0.013min|ω| / max|ω| = 0.013
Roe 的 |q̃| 在 q̃ = 0Roe's |q̃| at q̃ = 0min|q̃| = 2.0×10−3(一阶时壁面节点之间的面上正好为 0,见下)min|q̃| = 2.0×10−3 (exactly 0 on the faces between wall nodes at first order, see below)
S̃ 的两个分支 B = −c₂Ωthe two branches of S̃, B = −c₂Ωmin |B + c₂Ω| / Ω = 0.772(该处一阶导数连续)min |B + c₂Ω| / Ω = 0.772 (the first derivative is continuous there)
r 的截断 r = 10the cap r = 10min |r₀ − 10| / 10 = 0.785(fw 在 r = 10 已饱和,导数 ~10⁻³¹)min |r₀ − 10| / 10 = 0.785 (fw is saturated at r = 10; its slope is ~10⁻³¹)
壁面距离的最近边切换the wall distance switching edges凸物体:到凸多边形的距离一阶连续可微a convex body: the distance to a convex polygon is continuously differentiable

r 在 1 个控制体上被截断。修正分支只出现在 5 个来流节点上,而这些节点的 ν̃ 行被替换、源项不计算,所以本页二阶格式的残差用不到它(上表的余量也只在计算源项的控制体上取)。格点页一阶格式有一处例外:两个壁面节点之间的面,两侧速度都正好是 0,所以 q̃ = 0,正好落在 |q̃| 的不可导点上。导数取 |q̃| 的正分支;这些导数项只与壁面节点的速度相乘,而任何前向解 v 在壁面节点的速度分量上恒为零(它们的行被替换),所以设计导数与分支的选法无关,只有壁面节点动量分量的伴随值依赖它。

r is capped in 1 control volume. The modified branch occurs only at 5 inflow nodes, whose ν̃ rows are replaced and whose source is not evaluated, so this page's second-order residual does not use it (the margins of the table are taken over the control volumes whose source is evaluated). The node page at first order has one exception: on a face between two wall nodes both velocities are exactly 0, so q̃ = 0 and the face sits exactly on the kink of |q̃|. The derivative takes the positive branch of |q̃|; these terms multiply only the wall nodes' velocities, and every tangent solution v is zero in the wall nodes' velocity components (their rows are replaced), so the design derivatives do not depend on the choice; only the adjoint of the wall nodes' momentum components does.

下面的演示把这些分支画出来:fv1(χ)、fw(r) 与它在 r = 10 的截断、S̃/Ω 随 B/Ω 的两支,并把当前解(页首所选的阶)每个计算源项的控制体的值标在曲线上(ν̃ 行被替换的壁面节点与来流节点不画)。点离开分支点有多远,就是上表的余量。

The demo below draws these branches: fv1(χ), fw(r) with its cap at r = 10, and the two branches of S̃/Ω against B/Ω, with every control volume of the current solution (at the order chosen in the header) whose source is evaluated marked on the curves (the wall and inflow nodes, whose ν̃ rows are replaced, are left out). How far the points sit from a switch is the margin of the table above.

图 4.3Figure 4.3
第 5 节Section 5

残差 = 几遍循环:原始变量、梯度、面、源项、强边界行

The residual = passes: primitives, gradients, faces, source, strong rows

标量页面的残差是一个面循环。这里一个面要读两侧的梯度,而梯度要读整个模板的值,所以残差分成几遍:先把所有控制体的原始变量算出来,再算所有梯度,然后才是面通量和源项。

On the scalar pages the residual is one face loop. Here a face reads the gradients on both sides, and a gradient reads the values over its whole stencil, so the residual comes in passes: first the primitive variables of every control volume, then every gradient, and only then the face fluxes and the source.

UWGR原始变量primitive第 0 遍pass 0最小二乘least squares第 1 遍pass 1面与源项faces + source第 2、3 遍passes 2, 3面与源项也直接读 Wthe faces and the source also read W directly最后替换强边界行strong rows replaced last
图 5.1 · 残差分几遍计算:先把 U 转成原始变量 W,再算所有梯度 G,然后才是面通量与源项。顺序不能打乱:任何一个面都要用到两侧的梯度,而梯度要用到整个模板的 W。格点页最后还有一遍:替换壁面节点与来流节点的强边界行。Figure 5.1 · The residual in passes: U becomes the primitives W, then every gradient G is computed, and only then the face fluxes and the source. The order is forced: every face needs the gradients on both sides, and every gradient needs W over its whole stencil. The node page has one more pass at the end: the strong rows of the wall and inflow nodes are replaced.
W=π(U),G=ΓW,R(U)=F(W,G)−S(W,G,d)

π 在每个控制体上独立地把守恒变量换成原始变量;Γ 是线性的最小二乘算子(权重只依赖几何);F 是面通量的装配,S 是源项;格点页最后还有第 4 遍,替换壁面节点与来流节点的强边界行。下面的演示逐句执行这几遍:538 步,可以用上方的按钮直接跳到某一遍。

π turns each control volume's conserved variables into primitives, independently; Γ is the linear least-squares operator (its weights depend on the geometry only); F assembles the face fluxes and S the source. The demo below executes the passes statement by statement: 538 steps, and the buttons above it jump straight to a pass.

图 5.2Figure 5.2

最后一步 max|R| 在舍入误差量级:U* 是收敛解。注意第 4 遍:壁面节点的三行在所有循环之后才被替换,面循环写进这些行的值全部被覆盖;来流节点的四行也在这一遍替换。第 9 节的伴随要先处理这件事。

At the last step max|R| is at round-off: U* is the converged solution. Note pass 4: the three rows of each wall node are replaced after all the loops, overwriting whatever the face loop wrote there; the four rows of each inflow node are replaced in this pass too. The adjoint of Section 9 has to deal with this first.

第 6 节Section 6

求解:Jacobian、近似 Jacobian 与 Gauss–Seidel

The solve: the Jacobian, the approximate Jacobian and Gauss–Seidel

从残差到 Jacobian

From the residual to the Jacobian

A = ∂R/∂U 是 120×120 的矩阵,由 5×5 的块组成。一个面的通量读两侧的值与梯度,梯度又读整个模板,所以 A 的一行不只连到邻居,还连到邻居的邻居:264 个非零块。

A = ∂R/∂U is a 120×120 matrix of 5×5 blocks. A face's flux reads the values and gradients on both sides, and a gradient reads its whole stencil, so a row of A reaches past the neighbours to the neighbours' neighbours: 264 non-zero blocks.

A = ∂R/∂U(精确)A = ∂R/∂U (exact)264 个非零块264 non-zero blocksP(一阶 Roe + 薄剪切层)P (first-order Roe + thin shear layer)120 个非零块120 non-zero blocks
图 6.1 · 两个矩阵的 5×5 块(行、列都是控制体 1…24)。精确的 A 有 264 个非零块:一个面的通量读两侧的梯度,梯度又读整个模板,所以一行伸到邻居的邻居。近似 Jacobian P 只有 120 个:一阶 Roe 与薄剪切层只连接面的两侧。Gauss–Seidel 只需要 P。Figure 6.1 · The 5×5 blocks of the two matrices (rows and columns: control volumes 1…24). The exact A has 264 non-zero blocks: a face's flux reads the gradients on both sides, and each gradient reads its whole stencil, so a row reaches the neighbours of the neighbours. The approximate Jacobian P has 120: first-order Roe and the thin shear layer couple only the two sides of a face. Gauss–Seidel needs only P.

近似 Jacobian:一阶 Roe 加薄剪切层

The approximate Jacobian: first-order Roe plus the thin shear layer

Gauss–Seidel 用的不是 A,而是一个只连接面两侧的近似 P:对流部分是一阶 Roe(Jc(U) = ∂(Fc(U)·n̂)/∂U 是物理通量的 Jacobian,|J̃c| = Σk|Λk|rklkT 是它在两侧中心状态的 Roe 平均处取绝对值,lk 是左特征向量),粘性部分是薄剪切层(只保留修正梯度沿 Δx 的两点差分,系数冻结):

Gauss–Seidel does not use A but an approximation P that couples only the two sides of each face: first-order Roe for the convective part (Jc(U) = ∂(Fc(U)·n̂)/∂U is the Jacobian of the physical flux, and |J̃c| = Σk|Λk|rklkT its absolute value at the Roe average of the two centre states, lk being the left eigenvectors), and the thin shear layer for the viscous part (only the two-point difference along Δx of the corrected gradient, with frozen coefficients):

∂Φf∂UL≈12(Jc(UL)+∣J~c∣)∣n∣+Θf∂W∂U∣L∂Φf∂UR≈12(Jc(UR)−∣J~c∣)∣n∣−Θf∂W∂U∣R

Θf 是薄剪切层矩阵乘上两点系数 θf = nf·Δx/|Δx|²:动量行 θfμe(I + ⅓n̂n̂T),能量行加上功与导热 θfke,ν̃ 行 θfρa。(ρν̃, ρν̃) 对角元再加上 SA 源项对 ρν̃ 的导数,只在它为正(耗散占优、使对角增强)时加;对角块还加上伪时间项 V/Δt。壁面节点的三行、来流节点的四行是单位行。P 有 120 个非零块。

Θf is the thin-shear-layer matrix times the two-point coefficient θf = nf·Δx/|Δx|²: the momentum rows θfμe(I + ⅓n̂n̂T), the energy row adds the work and the conduction θfke, and the ν̃ row θfρa. The (ρν̃, ρν̃) entry also receives the SA source's derivative with respect to ρν̃ where it is positive (destruction dominating, so it strengthens the diagonal), and the diagonal blocks the pseudo-time term V/Δt. The three rows of a wall node and the four rows of an inflow node are unit rows. P has 120 non-zero blocks.

逐步推导:薄剪切层矩阵从哪里来

Step by step: where the thin-shear-layer matrix comes from

第一步,只留两点部分。在第 3 节的面梯度里只保留沿 Δx 的两点差,∇fφ ≈ (φR − φL)Δx/|Δx|²,并冻结所有系数。于是速度的面梯度矩阵是 ∇fu ≈ Δu ΔxT/|Δx|²(Δu = uR − uL)。

Step 1, keep only the two-point part. In the face gradient of Section 3 keep only the two-point difference along Δx, ∇fφ ≈ (φR − φL)Δx/|Δx|², and freeze every coefficient. The velocity's face-gradient matrix is then ∇fu ≈ Δu ΔxT/|Δx|² (Δu = uR − uL).

第二步,代入应力:

Step 2, put it into the stress:

τn≈μe∣Δx∣2[Δ𝐮 (Δx⋅n)+Δx (Δ𝐮⋅n)−23 (Δ𝐮⋅Δx) n]

第三步,Δx 平行于 n 时。Δx = |Δx|n̂、n = |n|n̂,两点系数 θf = n·Δx/|Δx|² = |n|/|Δx|,第二步化为

Step 3, when Δx is parallel to n. With Δx = |Δx|n̂ and n = |n|n̂, the two-point coefficient is θf = n·Δx/|Δx|² = |n|/|Δx|, and Step 2 becomes

τn≈θf μe[Δ𝐮+n^ (n^⋅Δ𝐮)−23 (n^⋅Δ𝐮) n^]=θf μe(I+13 n^n^T)Δ𝐮

第四步,能量与 ν̃ 两行。功 uavg·τn 用第三步的 τn,导热与 ν̃ 的扩散也只剩两点差(unavg = uavg·n̂):

Step 4, the energy and ν̃ rows. The work uavg·τn uses Step 3's τn, and the conduction and the ν̃ diffusion keep their two-point differences only (unavg = uavg·n̂):

𝐮avg⋅τn+ke∇ ⁣fT⋅n≈θf[μe(𝐮avg+13unavgn^)⋅Δ𝐮+ke ΔT],ρa ∇ ⁣fν~⋅n≈θf ρa Δν~

第五步,Θf。把三式按原始变量 (ρ, u, v, T, ν̃) 排成矩阵,就是上文近似 Jacobian 里的 Θf:Fv ≈ Θf(WR − WL),∂Fv/∂UR ≈ ΘfΠR,∂Fv/∂UL ≈ −ΘfΠL(Π = ∂W/∂U,第 8 节)。Δx 不平行于 n 时(歪斜的面),第二步里 Δx(Δu·n) 与 (Δu·Δx)n 两项不再化成 n̂n̂T:Θf 只是近似。P 本来只需要近似:它只影响迭代的快慢。

Step 5, Θf. Arranging the three in the primitive columns (ρ, u, v, T, ν̃) gives the Θf of the approximate Jacobian above: Fv ≈ Θf(WR − WL), ∂Fv/∂UR ≈ ΘfΠR, ∂Fv/∂UL ≈ −ΘfΠL (Π = ∂W/∂U, Section 8). When Δx is not parallel to n (a skewed face), the terms Δx(Δu·n) and (Δu·Δx)n of Step 2 no longer reduce to n̂n̂T: Θf is an approximation. P only needs to be one: it affects how fast the iteration converges, nothing else.

核对:把本页每个内部面的 Δx 转到 n 的方向、两侧取同一状态、梯度取零,粘性核的磁带给出的 ∂Fv/∂WR 与第三、四步的 Θf 相差 7.2×10−16(相对 Frobenius 范数)。本页的面并不正交:48 个内部面上 Δx 与 n 的夹角平均 18.8°,最大 42.4°(本页代码在构建时计算)。

Check: with the line Δx of every interior face of this page turned along n, the same state on both sides and zero gradients, the viscous kernel's taped ∂Fv/∂WR and the Θf of Steps 3 and 4 differ by 7.2×10−16 (relative, Frobenius norm). This page's faces are not orthogonal: over the 48 interior faces the angle between Δx and n is 18.8° on average and 42.4° at most (computed by this page's code at build time).

P 与 A 差多少?图 6.2 在一个面上比较磁带给出的直接块(一阶面状态、梯度固定,第 3 节 Roe 与粘性线性化的全部项)与 P 的块(第 3 节 Roe 第五步的前两项加上面的 Θf)。

How far is P from A? Figure 6.2 compares, on one face, the taped direct block (first-order face states, gradients held, every term of Section 3's linearisations of the Roe and viscous fluxes) with P's block (the first two terms of Step 5 of Section 3's Roe derivation plus the Θf above).

(a) 精确的 ∂Φf/∂UL(a) the exact ∂Φf/∂UL0.07−0.210.140.050−0.040.28−0.12−0.06−2e−60.03−0.180.200.057e−6−0.15−1.220.830.416e−69e−5−3e−32e−37e−40.10ρρuρvρEρν̃ρρuρvρEρν̃(b) P 的块(b) P's block0.07−0.180.110.050−0.090.30−0.14−0.0500.06−0.140.190.040−0.23−1.010.650.410−5e−4−1e−38e−47e−40.11ρρuρvρEρν̃ρρuρvρEρν̃(c) 两者之差(c) the difference3e−3−0.040.031e−300.05−0.010.02−0.01−2e−6−0.03−0.048e−39e−37e−60.09−0.210.18−8e−36e−66e−4−2e−31e−3−4e−6−0.01ρρuρvρEρν̃ρρuρvρEρν̃行:面通量的五个分量;列:UL 的五个分量。三个矩阵同一色标(|最大元| = 1.221)。rows: the five components of the face flux; columns: the five components of UL. One colour scale for all three (largest entry 1.221).
图 6.2 · 面 e17 的通量对左侧状态的直接块(两侧梯度固定,一阶面状态)。(a) 局部磁带给出的精确块:Roe 通量的全部三项(含 ∂|J̃c|/∂UL 乘跳跃的那一项)与粘性通量的全部系数导数。(b) 近似 Jacobian P 的块:½(Jc(UL) + |J̃c|)|n| + ΘfΠL。(c) 差就是被丢掉的那些项;按 Frobenius 范数,它是精确块的 18.6%。P 只决定迭代走多快,不改变终点(第 6 节)。Figure 6.2 · The direct block of face e17's flux with respect to its left state (the gradients of both sides held, first-order face states). (a) The exact block from the local tape: all three terms of the Roe flux (including ∂|J̃c|/∂UL times the jump) and every coefficient derivative of the viscous flux. (b) The block of the approximate Jacobian P: ½(Jc(UL) + |J̃c|)|n| + ΘfΠL. (c) The difference is what was dropped; in the Frobenius norm it is 18.6% of the exact block. P only sets how fast the iteration travels, not where it ends (Section 6).

R(U) = 0 怎样解

How R(U) = 0 is solved

用第 3 节的半离散方程 V dU/dt = −R(U) 做伪时间推进。记 ΔU = Uk+1 − Uk,每一步用隐式(后向 Euler)格式,并把 R 在当前状态线性化:

March the semi-discrete equation of Section 3, V dU/dt = −R(U), in pseudo time. With ΔU = Uk+1 − Uk, each step is implicit (backward Euler), with R linearised about the current state:

V ΔUΔt=−R(Uk+ΔU)≈−R(Uk)−A ΔU

把 AΔU 移到左边,就是每一步要解的线性方程:

Moving AΔU to the left gives the linear system of each step:

(VΔt+A)ΔU=−R(Uk)

V/Δt 是对角的:每个控制体取自己的伪时间步 Δti,由局部 CFL 数和该控制体的对流、粘性谱半径决定,所以各处推进的“时间”并不相同。把 A 换成近似 Jacobian Â,左边就是上面的 P;再用两次对称块 GS 近似求解(记作 K),就是本页的迭代:

V/Δt is diagonal: each control volume takes its own pseudo-time step Δti, set by a local CFL number and the control volume's convective and viscous spectral radii, so different places advance by different amounts of “time”. Replacing A by the approximate Jacobian  turns the left-hand side into the P above; solving with it approximately, by two symmetric block GS sweeps (written K), gives this page's iteration:

Uk+1=Uk−K R(Uk),P=VΔt+A^

一次对称扫描是 i = 1…N 的前扫接 N…1 的回扫;每个控制体解一个 5×5 的块方程,用到的是邻居最新的值。CFL 从 5 起按残差下降放大,上限 200;每 50 步检查一次,若这 50 步里最小的残差没有比此前最好的值再低 10%,就把上限减半(不低于 10),大步长下偶尔出现的伪时间二周期由此消失。一个 5×5 块的求逆就是全部的“线性代数”,不形成、不分解大矩阵。

One symmetric sweep is a forward pass over i = 1…N followed by a backward pass over N…1; each control volume solves a 5×5 block equation with its neighbours' latest values. The CFL number starts at 5 and grows as the residual falls, capped at 200; every 50 steps, if the smallest residual of those 50 is not 10 % below the best before, the cap is halved (down to 10), which settles the pseudo-time two-cycle that a large step occasionally produces. Inverting a 5×5 block is all the “linear algebra” there is: no large matrix is formed or factorised.

伪时间步只进 P(从而进 K),不进 R:它决定迭代怎样走、走多快,不改变终点。收敛时 R(U*) = 0,与 Δt、Â 和扫描次数都无关;本节开头的 A = ∂R/∂U 也不含时间项,所以第 8、9 节的前向与伴随方程 A v = −f、ATψ = −g 里也没有时间项。第 10、11 节迭代求解它们时用的也是这个 P,它同样只影响收敛的快慢。推进中还有一道保正:若整步会让某个控制体的 ρ 或 T 变化超过 20%,或让 ν̃ 变负,就按比例缩短这个控制体的步长;它也只改变路径。

The pseudo-time step enters P (and so K), not R: it decides how the iteration travels and how fast, not where it ends. At convergence R(U*) = 0 whatever Δt, Â and the number of sweeps; the A = ∂R/∂U at the start of this section carries no time term either, so neither do the tangent and adjoint equations of Sections 8 and 9, A v = −f and ATψ = −g. The iterations that solve them in Sections 10 and 11 use this P as well, and there too it only sets how fast they converge. The marching also keeps the state positive: if a full step would change a control volume's ρ or T by more than 20%, or make its ν̃ negative, that control volume's step is shortened in proportion; this too changes only the path.

图 6.3Figure 6.3

算例的状态

The state of the test case

二阶格式在第 90 次迭代满足判据(每个方程按自身尺度的残差都小于 10−13),然后继续到舍入底 1.1×10−15;一阶格式在第 37 次(这些是构建页面时在 Node.js 里测得的;页首的状态行是你的浏览器重算的,舍入底的末位可能不同)。收敛解处 ρ 在 [0.410, 1.261],p 在 [0.709, 2.328],ν̃ 最小 0.00819(来流 0.0600):处处为正,标准 SA 不需要任何截断。格点页第 0 级网格上的状态离连续解很远:24 个节点里 8 个壁面节点与 5 个来流节点的速度被强条件固定,流体只能从其余 11 个节点之间通过,最快处达到来流速度的 3.2 倍;出口的牵引力把压力维持在 p∞ 附近,密度低的地方温度就高(T 最高 1.89)。第 7 节的加密表与附录 A 说明这是离散误差:两种格式的阻力与导数随网格加密相互靠近。

The second-order scheme meets the criterion (every equation's residual, scaled by its own size, below 10−13) at iteration 90 and runs on to the round-off floor 1.1×10−15; the first-order scheme at iteration 37 (measured in Node.js when the page was built; the status line in the header is recomputed in your browser, and the last digits of the floor can differ). At the converged state ρ lies in [0.410, 1.261], p in [0.709, 2.328], and ν̃ is at least 0.00819 (free stream 0.0600): positive everywhere, and the standard SA needs no clipping. On level 0 the node page's state is far from the continuous solution: of the 24 nodes, the 8 wall nodes and the 5 inflow nodes have their velocity fixed by strong conditions, the flow has to pass between the other 11, and at its fastest it reaches 3.2 times the free-stream speed; the outlet's traction holds the pressure near p∞, so where the density is low the temperature is high (up to T = 1.89). The refinement table of Section 7 and Appendix A show that this is discretisation error: the drag and the derivatives of the two schemes approach each other as the mesh is refined.

图 6.4 把第 1 节的 SA 变量画在收敛解 U* 上,并标出第 4 节表中两个分支在哪些控制体上起作用。

Figure 6.4 draws the SA variables of Section 1 on the converged U*, and marks where the two branches of Section 4's table are active.

(a) ν̃(a) ν̃0.0000.060(b) μt/μ(b) μt/μ0.0000.092(c) SA 的分支(c) the SA branchesS̃ 的修正支modified S̃ branchr 截断在 10r capped at 10ρν̃ 行被替换,无源项ρν̃ row replaced, no source
图 6.4 · 收敛解 U* 上的 SA 变量(二阶格式)。(a) ν̃:来流值 0.0600,壁面节点上 ν̃ = 0,其余节点在 0.0082 到 0.0600 之间。(b) 涡粘性与分子粘性之比 μt/μ,最大 0.092:这张网格上的涡粘性很小,但每一项导数都照样要算。(c) 哪些控制体用 S̃ 的修正支(紫色,0 个)、哪些的 r 被截断在 10(红点,1 个);灰色是被替换了 ρν̃ 行的壁面与来流节点,它们不求源项。第 4 节的表给出每个分支离切换点的余量。Figure 6.4 · The SA variables of the converged U* (second order). (a) ν̃: the free stream carries 0.0600; ν̃ = 0 at the wall nodes and the other nodes lie between 0.0082 and 0.0600. (b) The ratio of eddy to molecular viscosity μt/μ, at most 0.092: the eddy viscosity on this mesh is small, but every derivative term is computed all the same. (c) Which control volumes take the modified branch of S̃ (violet, 0 of them) and which have r capped at 10 (red dots, 1); grey: the wall and inflow nodes whose ρν̃ row is replaced, which evaluate no source. Section 4's table gives each branch's margin from its switch.
第 7 节Section 7

目标函数:阻力系数

The objective: the drag coefficient

CD=𝐅⋅eDq∞,eD=(cos⁡α,sin⁡α),q∞=12ρ∞U∞2=0.7M2

F 是流体作用在物体上的力。格点页上壁面节点的动量行被替换了,力要从被替换之前的动量残差里取出来:一个壁面节点经内部对偶面流出的动量,等于物体经壁面半面作用在它上面的力;流体对物体的力是这个力的反作用。所以 F = −Σ壁面节点 Ri动量(替换前)。这是与离散动量守恒完全一致的“反作用力”。

F is the force the fluid exerts on the body. On the node page the wall nodes' momentum rows are replaced, so the force has to come from the momentum residual before the replacement: the momentum a wall node sends out through its interior dual faces equals the force the body exerts on it through its wall half-faces, and the fluid's force on the body is the reaction to that force. So F = −Σwall nodes Rimomentum (before replacement). This is the consistent “reaction force”: it agrees exactly with the discrete momentum balance.

来流方向 eDfree-stream direction eD
图 7.1 · 格点页的力:壁面节点动量方程在被替换之前的残差取负,就是流体经这个节点作用在物体上的力(红色箭头,已减去均匀来流压力的贡献,它的总和为零)。CD 把合力投影到来流方向。收敛解处 CD = 54.2003;逐点取节点压力与节点梯度应力的单边公式给出 47.9946。Figure 7.1 · The force on the node page: minus the momentum residual of a wall node before its rows are replaced is the force the fluid exerts on the body through that node (red arrows, with the uniform free-stream pressure removed, which sums to zero). CD projects the total onto the free-stream direction. At the converged state CD = 54.2003; the one-sided formula with the nodal pressure and the nodal gradients' stress gives 47.9946.

粗网格的阻力有多准

How accurate the coarse-mesh drag is

同一个问题在第 1、2 级加密网格(每级把每个单元一分为四)上的阻力:

The drag of the same problem on the meshes of levels 1 and 2 (each level divides every cell into four):

级level控制体control volumesCD单边公式one-sided formula
02454.200347.9946
18011.428613.3293
22887.27208.1613

第 0 级的阻力是第 2 级的 7.5 倍:这张网格上 13 个节点的速度被强条件固定(第 6 节)。随着加密两种格式相互靠近(第 2 级:格点 7.272,格心 6.650;附录 A 算到第 4 级:格点 6.440,格心 6.599);单边公式(节点压力加节点梯度应力)比反作用力收敛得慢。从第 0 级到第 4 级,本页的 CD 变化 −88%,三个导数:dCD/dα −91%、dCD/dM −72%、dCD/dμref −65%;其中对 α 的导数比阻力变得多(第 12 节、附录 A)。本页关心的是离散问题的导数:它在每一级网格上都是那一级离散问题的精确导数,但第 0 级的值不能当作连续问题导数的近似。

The level-0 drag is 7.5 times level 2's: on this mesh 13 nodes have their velocity fixed by strong conditions (Section 6). With refinement the two schemes approach each other (level 2: node 7.272, cell 6.650; Appendix A goes to level 4: node 6.440, cell 6.599); the one-sided formula (nodal pressure plus the nodal gradients' stress) converges more slowly than the reaction force. From level 0 to level 4 this page's CD changes by −88%, and its three derivatives: dCD/dα by −91%, dCD/dM by −72%, dCD/dμref by −65%; the derivatives with respect to α change more than the drag (Section 12 and Appendix A). What this page is about is the derivative of the discrete problem: on every mesh it is the exact derivative of that mesh's discrete problem, but the level-0 value must not be taken as an approximation of the continuous problem's derivative.

伴随方程的右端项

The right-hand side of the adjoint equation

g = ∂CD/∂U 是伴随方程 ATψ = −g 的右端。它等于 residual_b 去掉第 4 遍(强边界行)那一步(第 9 节):权重 −eD/q∞ 放在壁面节点的动量行上,直接进入面循环的反向。这些行在替换之前的值正是目标所用的;若保留那一步,权重会经被替换的单位行直接进 Uˉ,结果就错了(两者相差 2.0,而去掉那一步与磁带给出的 g 相差 7.0×10−16,都按 g 的最大分量归一)。本页把整个目标函数录成一条磁带,反向扫描一次得到它:种子 CˉD=1,扫描返回的 Uˉ 就是 g。

g = ∂CD/∂U is the right-hand side of the adjoint equation ATψ = −g. It equals residual_b without its pass 4, the strong rows (Section 9): the weights −eD/q∞ on the wall nodes' momentum rows go straight into the reversed face loop. Those rows' values before the replacement are exactly what the objective uses; keeping the step would send the weights through the replaced unit rows straight into Uˉ, which is wrong (it differs by 2.0, while the version without the step differs from the taped g by 7.0×10−16, both relative to the largest entry of g). This page gets it from one reverse sweep of a tape of the objective: with the seed CˉD=1 the sweep returns Uˉ=g.

逐步推导:CD 的偏导数

Step by step: the partial derivatives of CD

第 8 节的 dCD/dD = ∂CD/∂D + ψTf 里,∂CD/∂D 是固定 U 时的偏导数。对三个流动参数它们都有闭式。

In Section 8's dCD/dD = ∂CD/∂D + ψTf, ∂CD/∂D is the partial derivative at fixed U. For the three flow parameters it has a closed form.

第一步,F 与参数。CD = F·eD/q∞。格点页的 F 是壁面节点替换前的动量行之和取负,这些行只收集内部对偶面的通量(壁面半面在面循环里跳过)。α 与 M 只进入来流数据,而壁面节点的对偶面不碰来流,所以固定 U 时 F 与 α、M 无关;μref 进入粘性通量。

Step 1, F and the parameters. CD = F·eD/q∞. On the node page F is minus the sum of the wall nodes' momentum rows before replacement, and those rows collect the fluxes of interior dual faces only (the face loop skips the wall half-faces). α and M enter the inflow data only, and no wall node's dual face touches the inflow, so at fixed U, F does not depend on α or M; μref enters the viscous fluxes.

第二步,α。deD/dα = (−sin α, cos α) = eL,与来流垂直,所以固定流场时转动来流方向,阻力的变化就是升力系数:

Step 2, α. deD/dα = (−sin α, cos α) = eL, perpendicular to the free stream, so turning the free-stream direction with the flow held changes the drag by the lift coefficient:

∂CD∂α∣U=𝐅⋅eLq∞=CL

第三步,M。q∞ = 0.7M²,dq∞/dM = 2q∞/M:

Step 3, M. q∞ = 0.7M², dq∞/dM = 2q∞/M:

∂CD∂M∣U=−𝐅⋅eDq∞2 dq∞dM=−2 CDM

第四步,μref。F 里依赖 μref 的只有粘性应力 τn,它对 μe 是线性的。μ = μref·1.4T1.5/(T + 0.4) 与 μref 成正比;μt = ρν̃fv1(χ) 经 χ = ρν̃/μ 依赖它:

Step 4, μref. The only part of F that depends on μref is the viscous stress τn, which is linear in μe. μ = μref·1.4T1.5/(T + 0.4) is proportional to μref; μt = ρν̃fv1(χ) depends on it through χ = ρν̃/μ:

∂μ∂μref=μμref,∂μt∂μref=ρν~fv1′ ∂χ∂μref=−ρν~ χfv1′μref,∂(τn)∂μref=τnμe ∂μe∂μref

格点页把它加在每个碰到壁面节点的内部对偶面上,符号与该节点在面上是 L 还是 R 一致(两个壁面节点之间的面两边抵消):

The node page sums it over the interior dual faces that touch a wall node, signed by whether the node is the face's L or R (a face between two wall nodes cancels):

∂CD∂μref∣U=eDq∞⋅∑f(±) τnμe  μavg−12∑ρν~ χfv1′μref

(±) 在壁面节点是面的 L 时取 +、是 R 时取 −。没有涡粘性时,这就是 CD 的粘性部分除以 μref:固定流场时粘性应力与 μref 成正比。涡粘性使它变小:固定 ν̃ 时 μref 增大,χ 减小,μt 也减小。

(±) is + where the wall node is the face's L and − where it is its R. Without eddy viscosity this is the viscous part of CD divided by μref: with the flow held, the viscous stress is proportional to μref. The eddy viscosity lowers it: at fixed ν̃ a larger μref means a smaller χ and a smaller μt.

第五步,g = ∂CD/∂U。F 读哪些状态,g 就在哪些控制体上非零:壁面节点的动量行读两侧的 W 与 G,G 又读整个模板。图 7.2 画出 g。

Step 5, g = ∂CD/∂U. g is non-zero exactly in the control volumes whose state F reads: the wall nodes' momentum rows read W and G on both sides, and G reads its whole stencil. Figure 7.2 draws g.

019.29颜色:|gi|(五个分量的 2-范数)colour: |gi| (the 2-norm of its five components)箭头:(gρu, gρv),按最大者缩放arrows: (gρu, gρv), scaled by the largest(小于最大者 5% 的不画)(those below 5% of it are not drawn)g ≠ 0 的控制体:24 / 24control volumes with g ≠ 0: 24 of 24eD = (cos α, sin α),α = 5.0°eD = (cos α, sin α), α = 5.0°
图 7.2 · 伴随方程的右端 g = ∂CD/∂U(格点页,U* 处)。CD 取壁面节点替换前的动量行,这些行读两侧的 W 与梯度,梯度又读整个模板,所以 g 伸到壁面节点的邻居的邻居:第 0 级网格只有三圈节点,24 个节点都有非零分量。g 是伴随迭代唯一的“源”:ATψ = −g 把它从这里传到整个网格(图 11.4)。Figure 7.2 · The right-hand side of the adjoint equation, g = ∂CD/∂U (node page, at U*). CD takes the wall nodes' momentum rows before replacement; those rows read W and the gradients on both sides, and the gradients read their whole stencils, so g reaches the neighbours of the wall nodes' neighbours: on level 0, with only three rings of nodes, all 24 nodes have non-zero entries. g is the only “source” of the adjoint iteration: ATψ = −g carries it from here over the whole mesh (Figure 11.4).

核对:本页 CL = −8.373317,与整条磁带给出的 ∂CD/∂α|U = −8.373317 相对差 0;−2CD/M = −542.0031,磁带 −542.0031,相对差 0;第四步的和 196.4841,磁带 196.4841,相对差 4.3×10−16。g 在 24 个控制体上非零(本页代码在构建时计算)。

Check: on this page CL = −8.373317, and the whole-residual tape gives ∂CD/∂α|U = −8.373317, a relative difference of 0; −2CD/M = −542.0031 against the tape's −542.0031, 0; Step 4's sum is 196.4841 against the tape's 196.4841, 4.3×10−16. g is non-zero in 24 control volumes (computed by this page's code at build time).

第 8 节Section 8

matrix-free 前向:计算 R˙=AU˙

Matrix-free forward mode: computing R˙=AU˙

为什么需要 A 与 AT 的乘积

Why products with A and AT are needed

120 个未知量 U120 unknowns U一个方程组 R(U) = 0one system R(U) = 051 个设计变量51 design variables48 个坐标 + α、M、μref48 coordinates + α, M, μref前向:51 次线性求解tangent: 51 linear solves伴随:1 次线性求解adjoint: 1 linear solve
图 8.1 · 一个目标 CD、51 个设计变量:前向每个设计方向要解一次 A v = −f,伴随只解一次 ATψ = −g,然后每个导数都是一次内积。Figure 8.1 · One objective CD, 51 design variables: the tangent needs one solve of A v = −f per design direction, the adjoint one solve of ATψ = −g, after which every derivative is one inner product.

对任何设计变量 D(迎角、马赫数、参考粘度、每个节点坐标),

For any design variable D (the angle of attack, the Mach number, the reference viscosity, each node coordinate),

dCDdD=∂CD∂D+gTv,Av=−f,f=∂R∂D⟺dCDdD=∂CD∂D+ψTf,ATψ=−g

前向每个设计变量解一次,伴随解一次就得到所有设计变量的导数。两种迭代都只需要一个动作:R˙=AU˙(residual_d)或 Uˉ=ATRˉ(residual_b)。

The tangent needs one solve per design variable, the adjoint one solve for all of them. Both iterations need only one action: R˙=AU˙ (residual_d) or Uˉ=ATRˉ (residual_b).

记号:点与横线

Notation: the dot and the bar

从这里起,对离散代码的求导都用自动微分的记号(Griewank 与 Walther):x˙ 是程序变量 x 的前向(切线)导数,xˉ 是它的反向(伴随)导数;反向把语句倒过来执行,累加写作 xˉ+=…,前向里被覆盖的量清零,xˉ←0。两个求解的结果沿用本页的名字 v 与 ψ:

From here on, every derivative of the discrete code is written in the notation of algorithmic differentiation (Griewank and Walther): x˙ is the forward (tangent) derivative of a program variable x, xˉ its reverse (adjoint) derivative; reverse mode runs the statements backwards, accumulating, xˉ+=…, and zeroing what the forward code overwrote, xˉ←0. The two solves keep this page's names, v and ψ:

v≡U˙  (D˙=1):C˙D=∂CD∂D+gTv=dCDdDRˉ=ψ:Uˉ=ATψ=−g,Dˉ=∂CD∂D+ψTf=dCDdDRˉTR˙=UˉTU˙(R˙=AU˙,  Uˉ=ATRˉ)

Dˉ 的显式部分 ∂CD/∂D 来自目标的反向扫描(种子 CˉD=1;第 7 节的 g 就是这种扫描对 U 给出的 Uˉ)。最后一行是对偶恒等式:第 9 节的点积检验在随机向量上核对它,第 11 节前向与伴随的导数估计逐步相等是它在迭代上的形式。

The explicit part ∂CD/∂D of Dˉ comes from a reverse sweep of the objective with CˉD=1 (Section 7's g is the Uˉ of such a sweep). The last line is the duality identity: the dot-product test of Section 9 checks it on random vectors, and the equal derivative estimates of the tangent and the adjoint iterations in Section 11 are its form along the iterations.

点、横线与 δ 各有其位。点与横线是离散代码的前向与反向导数(第 8–14、16 节与各节的逐步推导);代码与演示用 Tapenade 的名字,x_d ≡ x˙、x_b ≡ xˉ:residual_d 返回 R_d = A·U_d,residual_b 返回 U_b = AT·R_b。δ 是连续函数的变分,只出现在附录 A 的连续伴随里。

The dot, the bar and δ each have their place. The dot and the bar are the forward- and reverse-mode derivatives of the discrete code (Sections 8–14 and 16, and the step-by-step derivations); the code and the demos use Tapenade's names, x_d ≡ x˙ and x_b ≡ xˉ: residual_d returns R_d = A·U_d, residual_b returns U_b = AT·R_b. δ is the variation of a continuous function and appears only in the continuous adjoint of Appendix A.

对局部核求导:局部磁带

Differentiating the local kernels: local tapes

残差由三种核拼成:原始变量 π(每个控制体 5 进 5 出)、面核(内部对偶面读两侧的 W 与 G,共 30 个输入、5 个输出)、源项核(15 进 1 出)。每个核只写一次,同一份代码可以用实数、复数或“局部磁带”运行。磁带记下核里每个运算的值与它对一两个操作数的偏导数;向前扫一遍得到方向导数,向后扫一遍得到转置。本页在 U* 处对每个核录一次磁带(一个内部面最多 1224 个节点),反向扫 5 次得到它的 5×30 局部 Jacobian Jf。

The residual is built from three kinds of kernel: the primitives π (5 in, 5 out per control volume), the face kernel (an interior dual face reads W and G on both sides: 30 inputs, 5 outputs), and the source kernel (15 in, 1 out). Each kernel is written once, and the same code runs on real numbers, on complex numbers, or on a “local tape”. The tape records every operation's value and its partial derivatives with respect to its one or two operands; a forward sweep gives a directional derivative, a reverse sweep the transpose. This page tapes each kernel once at U* (at most 1224 nodes for an interior face) and sweeps it backwards 5 times for its 5×30 local Jacobian Jf.

装配:同样的几遍

Assembly: the same passes

˙U˙W˙G˙RΠ第 0 遍pass 0Γ第 1 遍pass 1Jf, Js第 2、3 遍passes 2, 3面与源项也直接读 ˙Wthe faces and the source also read ˙W directly最后替换强边界行strong rows replaced last
图 8.2 · 前向:同样的几遍、同样的顺序,每遍换成它的前向导数:W˙=ΠU˙,G˙=ΓW˙(最小二乘本来就是线性的,权重不变),面与源项换成在 U* 处的局部 Jacobian。Figure 8.2 · The tangent: the same passes in the same order, each replaced by its forward derivative: W˙=ΠU˙, G˙=ΓW˙ (the least squares is linear already, with the same weights), and the faces and the source by their local Jacobians at U*.
W˙=Π U˙,G˙=Γ W˙,Φ˙f=Jf(W˙[L]W˙[R]G˙[L]G˙[R]),R˙=AU˙=∑f±Φ˙f+∑iJs,i(W˙[i]G˙[i])
图 8.3Figure 8.3

为什么这正是 AU˙

Why this is exactly AU˙

链式法则:R = F(W, G) − S(W, G, d),W = π(U),G = ΓW,所以

The chain rule: R = F(W, G) − S(W, G, d), W = π(U), G = ΓW, hence

A=(∂F∂W−∂S∂W)Π+(∂F∂G−∂S∂G)Γ Π

演示最后一步把循环的结果 R_d 与显式的 A·U_d 相比(A 由 120 次同样的 residual_d 逐列拼出,只为对照)。随机向量的点积检验(第 9 节)也验证了这一点:两者之差 2.8×10−16(构建页面时算的,用的是第 9 节演示打开时那一组随机向量)。

The last step of the demo compares the loop's result R_d with the explicit product A·U_d (A assembled column by column from 120 calls of this same residual_d, for the comparison only). The dot-product test on random vectors (Section 9) confirms it too: a difference of 2.8×10−16 (computed when the page was built, with the pair of random vectors the demo of Section 9 opens with).

逐步推导:原始变量的 Jacobian Π

Step by step: the Jacobian Π of the primitives

第一步,写出 π。W = π(U):ρ = U1,u = U2/U1,v = U3/U1,ν̃ = U5/U1;由 ρE = ρ(cvT + ½|u|²),

Step 1, write π out. W = π(U): ρ = U1, u = U2/U1, v = U3/U1, ν̃ = U5/U1; from ρE = ρ(cvT + ½|u|²),

T=1cv(U4U1−U22+U322U12)

第二步,逐行求导。例如 ∂T/∂U1 = (−U4/U1² + (U2² + U3²)/U1³)/cv = (u² + v² − E)/(ρcv):

Step 2, differentiate row by row. For example ∂T/∂U1 = (−U4/U1² + (U2² + U3²)/U1³)/cv = (u² + v² − E)/(ρcv):

Π=∂W∂U=(10000−u/ρ1/ρ000−v/ρ01/ρ00u2+v2−Eρcv−uρcv−vρcv1ρcv0−ν~/ρ0001/ρ)

第三步,结构。Π 是下三角矩阵,对角元 1、1/ρ、1/ρ、1/(ρcv)、1/ρ 在 ρ > 0 时都不为零,所以它可逆。前向的第 0 遍是每个控制体一次 W˙=ΠU˙,伴随的最后一步是 Uˉ+=ΠTWˉ;ΠT 是上三角的,Uˉ 的 ρ 分量收集 Wˉ 全部五个分量的贡献。

Step 3, the structure. Π is lower triangular, and its diagonal 1, 1/ρ, 1/ρ, 1/(ρcv), 1/ρ never vanishes for ρ > 0, so it is invertible. Pass 0 of the tangent is W˙=ΠU˙ once per control volume, and the last step of the adjoint is Uˉ+=ΠTWˉ; ΠT is upper triangular, and the ρ component of Uˉ gathers contributions from all five components of Wˉ.

核对:在 U* 的每个控制体上,上面的 Π 与 model.js prim() 的磁带相差 4.0×10−16(相对)(本页代码在构建时计算)。

Check: in every control volume of U*, the Π above and the tape of model.js prim() differ by 4.0×10−16 (relative) (computed by this page's code at build time).

逐步推导:每一遍的前向语句

Step by step: the tangent statement of every pass

前向模式把程序的每一句 y = φ(x) 换成 y˙=φ′(x) x˙,语句的顺序不变,程序覆盖的量,前向也覆盖。下表把第 5 节 residual 的每一遍与 residual_d 的对应语句并排列出(上面演示里的清单执行的就是这组语句):左列在 U* 处取值,右列只多了点。

Forward mode replaces every statement y = φ(x) of the program by y˙=φ′(x) x˙, in the same order; what the program overwrites, the tangent overwrites too. The table puts each pass of Section 5's residual next to the matching statement of residual_d (the listing of the demo above runs these statements): the left column is evaluated at U*, the right one only adds the dots.

遍passresidualresidual_d
0 原始变量0 primitivesWi=π(Ui)W˙i=Πi U˙i
1 最小二乘梯度1 least-squares gradientsGi=∑jΓij (Wj−Wi)G˙i=∑jΓij (W˙j−W˙i)
2 面状态(二阶)2 face states (second order)WL+=WL+GL⋅ΔxLf,  WR+=WR+GR⋅ΔxRfW˙L+=W˙L+G˙L⋅ΔxLf,  W˙R+=W˙R+G˙R⋅ΔxRf
2 面通量2 face fluxΦf=roe(WL+,WR+)−visc(WL,WR,GL,GR)Φ˙f=roe′ (W˙L+,W˙R+)−visc′ (W˙L,W˙R,G˙L,G˙R)
2 分发2 scatterRL+=Φf,  RR–=ΦfR˙L+=Φ˙f,  R˙R–=Φ˙f
3 SA 源项3 SA sourceRi,ρν~+=Vi siR˙i,ρν~+=Vi s˙i
4 壁面节点4 wall nodesRi,k←Ui,kR˙i,k←U˙i,k
4 来流节点4 inflow nodesRi,k←Ui,k−U∞,kR˙i,k←U˙i,k

ΔxLf = xf − xL 与 ΔxRf = xf − xR 是从两侧中心到面点的重构方向(下标从起点到终点,与最小二乘模板的 Δxij = xj − xi 一样),一阶格式 W+ = W,没有这一行。roe′、visc′ 是两个核各自的局部 Jacobian;第 8 节的 Jf 是整个面核,把重构也算在里面,所以 Φ˙f=Jf(W˙L,W˙R,G˙L,G˙R) 就是上表面状态与面通量两行合起来。壁面半面不调用任何核;来流与出口半面的核在第 9 节与它们的伴随一起推导。第 4 遍的 k 是被替换的分量:壁面节点的 ρu、ρv、ρν̃,来流节点的 ρ、ρu、ρv、ρν̃。每一句的点只作用在它读的状态上:Γ、Vi、n、r 与 d 这些几何量在这里是常数,第 12 节才对它们求导。

ΔxLf = xf − xL and ΔxRf = xf − xR are the reconstruction directions from the two centres to the face point (the subscripts run from start to end, like the stencil's Δxij = xj − xi); the first-order scheme has W+ = W and no such row. roe′ and visc′ are the two kernels' own local Jacobians; Section 8's Jf is the whole face kernel, reconstruction included, so Φ˙f=Jf(W˙L,W˙R,G˙L,G˙R) is the table's face-states and face-flux rows together. A wall half-face calls no kernel; the kernels of the inflow and outlet half-faces are derived in Section 9 together with their adjoints. The k of pass 4 runs over the replaced components: ρu, ρv, ρν̃ of a wall node, and ρ, ρu, ρv, ρν̃ of an inflow node. Every dot acts only on the states a statement reads: the geometric quantities Γ, Vi, n, r and d are constants here, and Section 12 differentiates them.

逐步推导:Roe 核的前向语句

Step by step: the tangent statements of the Roe kernel

model.js 的 roe() 按下面九句计算一个面的对流通量(第 3 节的 Roe 推导给出了每一句的来由,第 3 节的清单是它们的缩写)。WL、WR 是两侧的面状态(二阶时是 W+),n̂ = n/|n|;n 在这里是常数。R 侧的 (1)、(2) 与 L 侧相同。

model.js's roe() computes a face's convective flux in the nine statements below (Section 3's Roe derivation gives the reason for each, and the listing of Section 3 abbreviates them). WL, WR are the two face states (W+ at second order), n̂ = n/|n|, and n is a constant here. The R side's (1) and (2) are the same as the L side's.

(1)  pL=ρLTL,qL=uLn^x+vLn^y,HL=cpTL+12(uL2+vL2)(2)  FL=ρLqL (1, uL, vL, HL, ν~L)+pL (0, n^x, n^y, 0, 0)(3)  ρ~=ρLρR,φ~=ρL φL+ρR φRρL+ρR(φ=u,v,H,ν~)(4)  c~2=(γ−1)(H~−12(u~2+v~2)),c~=c~2,q~=u~n^x+v~n^y(5)  Δφ=φR−φL(φ=ρ,p,u,v,q,ν~)(6)  Δ1,3=Δp∓ρ~c~ Δq2c~2,Δ2=Δρ−Δpc~2(7)  Λ1,3=q~∓c~,Λ2=Λ4=Λ5=q~(8)  diss=∑k=13∣Λk∣ Δk rk+∣q~∣ (Δ4r4+Δ5r5)(9)  Φ=∣n∣ 12(FL+FR−diss)

逐句求前向导数,就是 residual_d 在一个面上执行的语句,顺序相同:

Differentiating statement by statement gives what residual_d executes on one face, in the same order:

(1)  p˙L=ρ˙LTL+ρLT˙L,q˙L=u˙Ln^x+v˙Ln^y,H˙L=cpT˙L+uLu˙L+vLv˙L(2)  F˙L=(ρ˙LqL+ρLq˙L)(1,uL,vL,HL,ν~L)+ρLqL(0,u˙L,v˙L,H˙L,ν~˙L)+p˙L(0,n^x,n^y,0,0)(3)  ρ~˙=12ρ~(ρ˙LρL+ρ˙RρR),φ~˙=ρL φ˙L+ρR φ˙R+12(φL−φ~) ρ˙L/ρL+12(φR−φ~) ρ˙R/ρRρL+ρR(4)  (c~2)⋅=(γ−1)(H~˙−u~u~˙−v~v~˙),c~˙=(c~2)⋅2c~,q~˙=u~˙n^x+v~˙n^y(5)  Δφ˙=φ˙R−φ˙L(6)  Δ˙1,3=Δp˙∓(ρ~c~ Δq)⋅−2Δ1,3(c~2)⋅2c~2,Δ˙2=Δρ˙−Δp˙−Δp (c~2)⋅/c~2c~2(7)  ∣Λk∣⋅=sgn⁡(Λk) Λ˙k,Λ˙1,3=q~˙∓c~˙,Λ˙2=q~˙(8)  diss˙=∑k=13[(sgn⁡(Λk)Λ˙kΔk+∣Λk∣Δ˙k)rk+∣Λk∣Δkr˙k]+sgn⁡(q~) q~˙ (Δ4r4+Δ5r5)+∣q~∣ (Δ4r4+Δ5r5)⋅(9)  Φ˙=∣n∣ 12(F˙L+F˙R−diss˙)

(3) 把 √ρ 的前向导数 ρ˙/(2ρ) 代进了商的求导法则;(6) 里 (ρ~c~ Δq)⋅=ρ~˙c~ Δq+ρ~c~˙ Δq+ρ~c~ Δq˙。(8) 里特征向量的前向导数按它们的分量逐个加点:

(3) puts the tangent of √ρ, ρ˙/(2ρ), into the quotient rule; in (6) (ρ~c~ Δq)⋅=ρ~˙c~ Δq+ρ~c~˙ Δq+ρ~c~ Δq˙. In (8) the eigenvectors' tangents take a dot on each entry:

r˙1,3=(0, u~˙∓c~˙n^x, v~˙∓c~˙n^y, H~˙∓(q~˙c~+q~c~˙), ν~~˙),r˙2=(0, u~˙, v~˙, u~u~˙+v~v~˙, ν~~˙)(Δ4r4)⋅=ρ~˙ρ~ Δ4r4+ρ~ (0, Δu˙−Δq˙ n^x, Δv˙−Δq˙ n^y, u~˙Δu+u~Δu˙+v~˙Δv+v~Δv˙−q~˙Δq−q~Δq˙, 0)(Δ5r5)⋅=(0,0,0,0, ρ~˙ Δν~+ρ~ Δν~˙)

sgn Λk 是当前解所在那一支的符号:本页是亚声速流,声波的 q̃ ∓ c̃ 离零很远,q̃ 离零多远由第 4 节列出;在那一支上 |Λk| 是光滑的(格点页一阶时,壁面节点之间的面正好在 q̃ = 0 上,见第 4 节)。粘性核的前向语句就是第 3 节粘性通量推导的第三、五、六步,SA 源项的是第 3 节 SA 源项推导的十一步;边界面的核在第 9 节。这些语句都照写成了程序(kernels_ad.js,不调用 model.js 的核,只用它的常数),下面逐项核对。

sgn Λk is the sign on the branch the solution sits on: the flow on this page is subsonic, the acoustic speeds q̃ ∓ c̃ are far from zero, and Section 4 lists how far q̃ is from it; on that branch |Λk| is smooth (on the node page at first order the faces between wall nodes sit exactly at q̃ = 0; see Section 4). The viscous kernel's tangent statements are Steps 3, 5 and 6 of Section 3's viscous-flux derivation, the SA source's the eleven steps of Section 3's SA derivation; the boundary faces' kernels are in Section 9. All these statements are also written out as a program (kernels_ad.js, which calls no kernel of model.js and uses only its constants), checked item by item below.

核对:在本页全部 48 个内部面上,沿随机方向,上面九句前向语句给出的 Φ˙ 与 model.js roe() 的复数步长(步长 10−30)最大相对差 9.4×10−16;粘性核的前向语句 1.3×10−15;整个面核(重构、Roe 减粘性)2.0×10−15;来流半面 3.3×10−16、出口半面 1.7×10−15;两种来流处理的核在本页状态上 4.9×10−16;SA 源项(11 个控制体,连 d 一起)2.9×10−15;原始变量 4.7×10−16。把这些语句按上表拼成 residual_d,与 core.js 的 applyA(局部磁带)相差 5.8×10−16,与残差的中心差分(步长 10−6)相差 3.8×10−10(本页代码在构建时计算)。

Check: on all 48 interior faces of this page, along random directions, the Φ˙ of the nine tangent statements above and the complex step of model.js's roe() (step 10−30) differ by at most 9.4×10−16 (relative); the viscous kernel's tangent statements by 1.3×10−15; the whole face kernel (reconstruction, Roe minus viscous) by 2.0×10−15; the inflow half-faces by 3.3×10−16 and the outlet half-faces by 1.7×10−15; both inflow treatments' kernels at this page's state by 4.9×10−16; the SA source (11 control volumes, d included) by 2.9×10−15; the primitives by 4.7×10−16. Assembled into residual_d as in the table, the statements agree with core.js's applyA (local tapes) to 5.8×10−16 and with a central difference of the residual (step 10−6) to 3.8×10−10 (computed by this page's code at build time).

图 8.4 把这些语句放到网格上执行:U˙ 取第 10 节的前向解 v(迎角方向,α˙=1),面一个接一个地把 Φ˙f 分给两侧,源项一个接一个地加到 ρν̃ 行上,每个控制体的五个分量随之累加。扫到最后 R˙=Av=−f:α 只经来流数据进入残差,所以 f 只在来流节点上不为零,其余控制体上各个面与源项的贡献相消(到求解判据 10−13)。

Figure 8.4 runs these statements on the mesh: U˙ is Section 10's tangent solution v (along the angle of attack, α˙=1), the faces one after another send Φ˙f to their two sides, the sources one after another add into the ρν̃ rows, and the five components of every control volume accumulate. At the end R˙=Av=−f: α enters the residual only through the inflow data, so f is non-zero only at the inflow nodes, and everywhere else the faces' and sources' contributions cancel (to the solve's criterion, 10−13).

图 8.4Figure 8.4
第 9 节Section 9

matrix-free 伴随:计算 Uˉ=ATRˉ

Matrix-free adjoint mode: computing Uˉ=ATRˉ

转置一个乘积要把因子倒过来、每个因子转置。反向把第 8 节的几条语句倒过来执行,从种子 Rˉ 出发:

Transposing a product reverses the factors and transposes each. Reverse mode runs the statements of Section 8 backwards, from the seed Rˉ:

Gˉ=(∂F∂G−∂S∂G)TRˉWˉ=(∂F∂W−∂S∂W)TRˉ+ΓTGˉUˉ=ΠTWˉ=ATRˉ
¯U¯W¯G¯RΠT​第 0 遍反向pass 0 reversedΓT​第 1 遍反向pass 1 reversed(F, S)T​第 2、3 遍反向passes 2, 3 reversed面与源项也直接累加到 ¯Wthe faces and the source also accumulate into ¯W directly先取强边界行strong rows taken first
图 9.1 · 伴随:同样的几遍,倒序,每遍换成它的转置。从种子 Rˉ 出发,面与源项先把权重累加到 Wˉ 与 Gˉ 上;然后 ΓT 把梯度的权重送回整个模板;最后 ΠT 把 Wˉ 变回守恒变量的 Uˉ。被替换的壁面行最先处理。Figure 9.1 · The adjoint: the same passes, in reverse, each replaced by its transpose. From the seed Rˉ, the faces and the source first accumulate their weights into Wˉ and Gˉ; ΓT then sends the gradients' weights back over their whole stencils; finally ΠT turns Wˉ into the conserved variables' Uˉ. The replaced wall rows come first.
  • 面与源项的转置:原来“写 R[L]、R[R]”的地方变成“读 Rˉ[L]−Rˉ[R]”,一个 5 维权重经 JfT 变成 30 个,累加到 Wˉ 与 Gˉ 上。The transpose of the faces and the source: where R[L] and R[R] were written, Rˉ[L]−Rˉ[R] is read, and one 5-vector of weights becomes 30 through JfT, accumulated into Wˉ and Gˉ.
  • 最小二乘的转置 ΓT:前向里梯度从整个模板收集,伴随里梯度的权重送回整个模板(每个模板点加,自己减)。The transpose of the least squares, ΓT: in the tangent a gradient gathers from its whole stencil, in the adjoint the gradient's weight is sent back to its whole stencil (added at each stencil point, subtracted at its own).
  • 原始变量的转置 ΠT:每个控制体一个 5×5 转置乘法,累加到 Uˉ 上。The transpose of the primitives, ΠT: one 5×5 transposed product per control volume, accumulated into Uˉ.
  • 壁面行:前向里它们在最后被覆盖,伴随里它们最先处理:权重直接加到 Uˉ 上,并在 Rˉ 中清零(Rˉ←0),因为循环写进这些行的值从未进入结果。The wall rows: overwritten last in the tangent, handled first in the adjoint: their weights go straight into Uˉ and are zeroed in Rˉ (Rˉ←0), because what the loops wrote into those rows never reached the result.
  • 来流行:四行 U − U∞ 与壁面行一样,权重直接加到 Uˉ 上,并在 Rˉ 中清零。The inflow rows: the four rows U − U∞ are handled like the wall rows, their weights straight into Uˉ and zeroed in Rˉ.
图 9.2Figure 9.2

点积检验

The dot-product test

取随机的 U˙ 与 Rˉ:如果 residual_b 真是 residual_d 的转置,第 8 节的对偶恒等式两边应在舍入误差内相等:

Take random U˙ and Rˉ: if residual_b really is the transpose of residual_d, the two sides of Section 8's duality identity agree to round-off:

RˉTR˙=UˉTU˙,R˙=AU˙ (residual_d),Uˉ=ATRˉ (residual_b)
图 9.3Figure 9.3

图 9.4 把点积检验拆开:对偶恒等式不只在两端成立,在相邻两遍之间的每一处切口都成立,因为每一遍的伴随就是它自己的转置。用上面演示打开时那一组随机向量(第 8 节引用的那一组),五处(两端与三处切口)的内积都是同一个数,也就是演示先打印的那个数。

Figure 9.4 takes the dot-product test apart: the duality identity holds not only at the two ends but at every cut between two adjacent passes, because the adjoint of every pass is its own transpose. With the pair of random vectors the demo above opens with (the pair Section 8 quotes), the inner products at all five places (the two ends and the three cuts) are the same number, the one the demo prints first.

前向:自上而下tangent: top to bottom伴随:自下而上adjoint: bottom to top两边的量的内积the inner product of the two sides˙U¯U = AT¯R⟨¯U, ˙U⟩1.60999749059˙W = Π˙U¯W + ΓT¯G⟨¯W + ΓT¯G, ˙W⟩ + 第 4 遍⟨¯W + ΓT¯G, ˙W⟩ + pass 41.60999749059˙W, ˙G = Γ˙W¯W, ¯G⟨¯W, ˙W⟩ + ⟨¯G, ˙G⟩ + 第 4 遍⟨¯W, ˙W⟩ + ⟨¯G, ˙G⟩ + pass 41.60999749059˙Φf, ˙si¯Φf, ¯siΣf ¯Φf·˙Φf + Σi ¯si ˙si + 第 4 遍Σf ¯Φf·˙Φf + Σi ¯si ˙si + pass 41.60999749059˙R = A˙U¯R⟨¯R, ˙R⟩1.60999749059ΠΠTΓΓTJf, JsJfT, JsT分发,第 4 遍scatter, pass 4第 4 遍,收集pass 4, gather第 4 遍(被替换的行)的一份 = 0.265970337898:它在前向里最后执行、在伴随里最先执行,pass 4's share (the replaced rows) = 0.265970337898: it runs last in the tangent and first in the adjoint,所以中间三处切口都把它加上so the three middle cuts add it
图 9.4 · 对偶恒等式在两端与每一处切口上都成立。左列是前向 residual_d 的量,由各遍(箭头)自上而下算出;右列是伴随 residual_b 的量,自下而上;最上与最下两行是两端,中间三行是相邻两遍之间的切口,每一行中间是左右两个量的内积。每一遍的伴随都是它自己的转置,所以五个内积相等:取本节点积演示打开时的那一组随机向量(U˙ 与 Rˉ),它们在本页是同一个数,最大相对差 9.7×10−16。格点页的第 4 遍(强边界行)在前向里最后执行,在伴随里最先执行:被替换的行把权重直接交给 Uˉ,它的那一份在中间三处切口单独加上。Figure 9.4 · The duality identity holds at the two ends and at every cut. The left column is the quantities of the tangent residual_d, computed top to bottom by the passes (the arrows); the right column those of the adjoint residual_b, bottom to top; the top and bottom rows are the two ends and the three rows between them the cuts between two adjacent passes, each with the inner product of its two quantities in the middle. The adjoint of every pass is its own transpose, so the five inner products are equal: with the pair of random vectors this section's dot-product demo opens with (U˙ and Rˉ) they are the same number on this page, to 9.7×10−16 (relative). On the node page pass 4 (the strong rows) runs last in the tangent and first in the adjoint: the replaced rows hand their weights straight to Uˉ, and their share is added at the three middle cuts.

核对:五处的内积最大相对差 9.7×10−16;两端与 core.js 的 applyA、applyAT 算出的 RˉTAU˙ = 1.61、(ATRˉ)TU˙ = 1.61 一致(本页代码在构建时计算)。

Check: the five inner products differ by at most 9.7×10−16 (relative); the two ends agree with RˉTAU˙ = 1.61 and (ATRˉ)TU˙ = 1.61 from core.js's applyA and applyAT (computed by this page's code at build time).

逐步推导:每一遍的伴随语句(倒序、累加)

Step by step: the adjoint statement of every pass (reversed, accumulating)

反向模式把每一句 y = φ(x) 换成 xˉ+=φ′(x)Tyˉ,整段程序从最后一句倒着执行;前向里覆盖了某个量的语句,在反向里先把这个量的伴随交出去,再把它清零(yˉ←0)。下表按反向执行的顺序排列:第 4 遍最先,第 0 遍最后;每一行的右列是左列那一句的转置。

Reverse mode replaces every statement y = φ(x) by xˉ+=φ′(x)Tyˉ and runs the whole program backwards from its last statement; a statement that overwrote a variable first hands that variable's adjoint on and then zeroes it (yˉ←0). The table lists the statements in the order reverse mode runs them, pass 4 first and pass 0 last; the right column of each row is the transpose of its left column.

遍passresidualresidual_b(按表的顺序执行)residual_b (run in the table's order)
4 来流节点4 inflow nodesRi,k←Ui,k−U∞,kUˉi,k+=Rˉi,k,  Rˉi,k←0
4 壁面节点4 wall nodesRi,k←Ui,kUˉi,k+=Rˉi,k,  Rˉi,k←0
3 SA 源项3 SA sourceRi,ρν~+=Vi sisˉi=Vi Rˉi,ρν~;  (Wˉi,Gˉi)+=Js,iT sˉi/Vi
2 分发2 scatterRL+=Φf,  RR–=ΦfΦˉf=RˉL−RˉR
2 面通量2 face fluxΦf=roe(WL+,WR+)−visc(WL,WR,GL,GR)(WˉL+,WˉR+)=roe′T Φˉf,  (WˉL,WˉR,GˉL,GˉR)–=visc′T Φˉf
2 面状态(二阶)2 face states (second order)WL+=WL+GL⋅ΔxLfWˉL+=WˉL+,  GˉL+=WˉL+ ΔxLfT
1 最小二乘梯度1 least-squares gradientsGi=∑jΓij (Wj−Wi)Wˉj+=Γij⋅Gˉi,  Wˉi–=Γij⋅Gˉi
0 原始变量0 primitivesWi=π(Ui)Uˉi+=ΠiT Wˉi

累加是因为一个量被几句读到,它的伴随就要收集几份:Wi 被它自己的面状态、它所在的每个最小二乘模板、它的每个面和它自己的 SA 源项读到,所以 Wˉi 在这四处都有 +=。Js,i 是源项核 Visi 的局部 Jacobian(第 8 节),所以除以 Vi 与 sˉi 里的 Vi 抵消。第 4 遍的反向先于一切:被替换的行在前向里最后才被覆盖,循环写进这些行的值从未进入结果,所以它们的权重直接交给 Uˉ 并清零。

The += is there because a variable read by several statements must collect one share from each: Wi is read by its own face states, by every least-squares stencil it belongs to, by each of its faces and by its own SA source, so Wˉi has a += at all four places. Js,i is the local Jacobian of the source kernel Visi (Section 8), so the division by Vi cancels the Vi in sˉi. Pass 4 reversed comes before everything: the replaced rows were overwritten last in the forward code, and what the loops wrote into them never reached the result, so their weights go straight into Uˉ and are zeroed.

逐步推导:Roe 核的伴随语句

Step by step: the adjoint statements of the Roe kernel

把第 8 节的九句倒过来:从 Φˉ 出发,(9) 最先、(1) 最后;每一句把它左边那个量的伴随按偏导数分给右边的每个输入,一个输入被几句读到就收集几份。跳跃的伴随 Δφ‾ 与质量通量的伴随 ρLqL‾ 是中间量:(5) 把前者 + 给 R 侧、− 给 L 侧。

Reverse the nine statements of Section 8: from Φˉ, (9) first and (1) last; each statement shares the adjoint of its left-hand side among its inputs by the partial derivatives, and an input read by several statements collects a share from each. The jumps' adjoints Δφ‾ and the mass flux's adjoint ρLqL‾ are intermediates: (5) sends the former to the R side with + and to the L side with −.

(9)  FˉL+=12∣n∣ Φˉ,FˉR+=12∣n∣ Φˉ,dissˉ=−12∣n∣ Φˉ(8)  Δˉk=∣Λk∣ rkTdissˉ,Λˉk=sgn⁡(Λk) Δk rkTdissˉ,rˉk=∣Λk∣ Δk dissˉ(k=1,2,3)q~ˉ+=sgn⁡(q~) (Δ4r4+Δ5r5)Tdissˉ,ρ~ˉ+=∣q~∣ρ~ (Δ4r4+Δ5r5)TdissˉΔu‾+=∣q~∣ρ~(dissˉρu+u~ dissˉρE),Δv‾+=∣q~∣ρ~(dissˉρv+v~ dissˉρE),Δν~‾+=∣q~∣ρ~ dissˉρν~Δq‾–=∣q~∣ρ~(n^xdissˉρu+n^ydissˉρv+q~ dissˉρE),(u~ˉ,v~ˉ)+=∣q~∣ρ~ (Δu,Δv) dissˉρE,q~ˉ–=∣q~∣ρ~ Δq dissˉρE(7)  q~ˉ+=Λˉ1+Λˉ2+Λˉ3,c~ˉ+=Λˉ3−Λˉ1(6)  Δp‾+=Δˉ1+Δˉ32c~2−Δˉ2c~2,Δρ‾+=Δˉ2,c~2‾+=Δp Δˉ2c~4−Δ1Δˉ1+Δ3Δˉ3c~2(ρ~ˉ, c~ˉ, Δq‾)+=Δˉ3−Δˉ12c~2 (c~ Δq, ρ~ Δq, ρ~c~)(5)  φˉR+=Δφ‾,φˉL–=Δφ‾(φ=ρ,p,u,v,q,ν~)(4)  (u~ˉ,v~ˉ)+=q~ˉ (n^x,n^y),c~2‾+=c~ˉ2c~,H~ˉ+=(γ−1) c~2‾,(u~ˉ,v~ˉ)–=(γ−1) (u~,v~) c~2‾(3)  φˉL+=ρL φ~ˉρL+ρR,ρˉL+=(φL−φ~) φ~ˉ2ρL (ρL+ρR)(φ=u,v,H,ν~),ρˉL+=ρ~ ρ~ˉ2ρL(2)  ρLqL‾=(1, uL, vL, HL, ν~L)⋅FˉL,ρˉL+=qL ρLqL‾,qˉL+=ρL ρLqL‾(uˉL, vˉL, HˉL, ν~ˉL)+=ρLqL (FˉL,ρu, FˉL,ρv, FˉL,ρE, FˉL,ρν~),pˉL+=n^xFˉL,ρu+n^yFˉL,ρv(1)  TˉL+=cpHˉL+ρLpˉL,uˉL+=uLHˉL+n^xqˉL,vˉL+=vLHˉL+n^yqˉL,ρˉL+=TL pˉL

(3)、(2)、(1) 对 R 侧同样各有一组。(8) 的 rˉk 还要按特征向量的分量送回 Roe 平均量(rˉk,ρ𝐮 是它的两个动量分量):r1、r2、r3 都给 (u~ˉ,v~ˉ)+=rˉk,ρ𝐮 与 ν~~ˉ+=rˉk,ρν~;r1,3 里的 ∓c̃n̂ 与 H̃ ∓ q̃c̃ 给 c~ˉ+=∓(n^⋅rˉk,ρ𝐮+q~ rˉk,ρE)、q~ˉ+=∓c~ rˉk,ρE、H~ˉ+=rˉk,ρE(上面的符号属于 k = 1);r2 的能量分量 ½(ũ² + ṽ²) 给 (u~ˉ,v~ˉ)+=(u~,v~) rˉ2,ρE。按 model.js 的写法,它们与 (8) 的各行在同一段代码里完成。图 9.5 在一个面上逐句执行第 8 节的前向与这里的反向,每一句的值、点与横线都标出来。

(3), (2) and (1) have the same set for the R side. The rˉk of (8) still has to go back to the Roe averages entry by entry (rˉk,ρ𝐮 is its two momentum entries): r1, r2 and r3 all give (u~ˉ,v~ˉ)+=rˉk,ρ𝐮 and ν~~ˉ+=rˉk,ρν~; the ∓c̃n̂ and H̃ ∓ q̃c̃ of r1,3 give c~ˉ+=∓(n^⋅rˉk,ρ𝐮+q~ rˉk,ρE), q~ˉ+=∓c~ rˉk,ρE and H~ˉ+=rˉk,ρE (the upper sign for k = 1); r2's energy entry ½(ũ² + ṽ²) gives (u~ˉ,v~ˉ)+=(u~,v~) rˉ2,ρE. As model.js is written, these are done in the same lines as the rows of (8). Figure 9.5 runs Section 8's forward statements and these reverse ones on one face, statement by statement, with every statement's value, dot and bar.

图 9.5Figure 9.5

核对:在本页 48 个内部面上,用随机的 Φˉ 与 W˙L,W˙R,这组伴随语句与第 8 节的前向语句满足 ΦˉTΦ˙=WˉLTW˙L+WˉRTW˙R,最大差 2.7×10−16(相对各乘积的绝对值之和);它们给出的 (WˉL,WˉR) 与 roe() 局部磁带的反向扫描相差 3.7×10−16(本页代码在构建时计算)。

Check: on the 48 interior faces of this page, with random Φˉ and W˙L,W˙R, these adjoint statements and the tangent statements of Section 8 satisfy ΦˉTΦ˙=WˉLTW˙L+WˉRTW˙R to 2.7×10−16 (relative to the sum of the products' sizes); the (WˉL,WˉR) they give and a reverse sweep of roe()'s local tape differ by 3.7×10−16 (computed by this page's code at build time).

逐步推导:粘性核与 SA 源项的伴随语句

Step by step: the adjoint statements of the viscous kernel and of the SA source

粘性核(第 3 节粘性通量推导的第一、二、四步,偏导数取自第三、五步)倒着执行。面通量是 Φ = roe − visc,所以从 Fˉv=−Φˉ 出发;下标 ρu、ρE、ρν̃ 是 Fv 的分量,下标 L,R 表示两侧各有一句:

The viscous kernel (Steps 1, 2 and 4 of Section 3's viscous-flux derivation, with the partials of Steps 3 and 5) runs backwards. The face flux is Φ = roe − visc, so it starts from Fˉv=−Φˉ; the subscripts ρu, ρE, ρν̃ are Fv's components, and a subscript L,R stands for one statement on each side:

τˉ=(Fˉρ𝐮v+𝐮avg FˉρEv) nT,(uˉ,vˉ)L,R+=12 τn FˉρEv,kˉe=(∇ ⁣fT⋅n) FˉρEv,∇ ⁣fT‾=ke n FˉρEvρa‾=(∇ ⁣fν~⋅n) Fˉρν~v,∇ ⁣fν~‾=ρa n Fˉρν~vμˉe=tr⁡(τˉTτ)μe,∇ ⁣f𝐮‾=μe(τˉ+τˉT−23tr⁡(τˉ) I)μˉavg=μˉe+cpPr kˉe+ρa‾σ,μˉtavg=μˉe+cpPrt kˉe,(ρˉ,ν~ˉ)L,R+=ρa‾2σ (ν~,ρ)L,Rμˉt,L,R=12μˉtavg:(ρˉ,ν~ˉ)L,R+=(fv1+χfv1′) (ν~,ρ)L,R μˉt,L,R,μˉL,R=12μˉavg−χ2fv1′ μˉt,L,R,TˉL,R+=μT μˉL,R∇φavg‾=(I−Δx^ Δx^T) ∇ ⁣fφ‾,φˉR+=Δx⋅∇ ⁣fφ‾∣Δx∣2,φˉL–=Δx⋅∇ ⁣fφ‾∣Δx∣2,GˉL,φ,GˉR,φ+=12 ∇φavg‾

第一行的 τˉ 把动量行与能量行里的同一个 τn 合起来:能量行的功 uavg·τn 也读 τn。第三行来自 τn = μe[(∇fu + ∇fuT)n − ⅔tr(∇fu)n]:它对 μe 与 ∇fu 都是线性的,所以对 ∇fu 的伴随就是把 τˉ 对称化,再在对角线上减去 ⅔tr(τˉ)。最后一行对 φ = u、v、T、ν̃ 各一句(∇fu 的伴随的两行就是 ∇fu、∇fv 的伴随):修正梯度的转置把 Δx 方向的权重交给两个中心值,垂直方向的权重平分给两侧的梯度。

The τˉ of the first line joins the momentum rows and the energy row, whose work uavg·τn reads the same τn. The third line comes from τn = μe[(∇fu + ∇fuT)n − ⅔tr(∇fu)n], which is linear in μe and in ∇fu, so the adjoint with respect to ∇fu symmetrises τˉ and subtracts ⅔tr(τˉ) on the diagonal. The last line is one statement per φ = u, v, T, ν̃ (the two rows of the adjoint of ∇fu are those of ∇fu, ∇fv): the transpose of the corrected gradient hands the weight along Δx to the two centre values and splits the weight across Δx between the two gradients.

SA 源项(第 3 节 SA 源项推导的十一步)倒着执行,从 sˉ=ViRˉi,ρν~ 出发。FB、FΩ、ft2′、fv2′ 与 μT 是第 3 节第一至第八步的偏导数;Gˉv,x、Gˉu,y 是 ∂v/∂x、∂u/∂y 在 Gˉ 里的分量:

The SA source (the eleven steps of Section 3's SA derivation) runs backwards from sˉ=ViRˉi,ρν~. FB, FΩ, ft2′, fv2′ and μT are the partials of Steps 1 to 8 of Section 3; Gˉv,x and Gˉu,y are the entries of Gˉ for ∂v/∂x and ∂u/∂y:

ρˉ–=(b∣∇ν~∣2+Q) sˉ,Qˉ=−ρ sˉ,Gˉρ+=a ∇ν~ sˉ,Gˉν~+=(a ∇ρ−2ρb ∇ν~) sˉ,aˉ=(∇ρ⋅∇ν~) sˉνˉ=aˉ/σ,ν~ˉ+=aˉ/σfˉw=−cw1(ν~d)2Qˉ,fˉt2=cb1(1κ2(ν~d)2−S~ν~)Qˉ,S~ˉ=cb1(1−ft2) ν~ Qˉν~ˉ+=(cb1(1−ft2) S~−2(cw1fw−cb1κ2ft2)ν~d2)Qˉ,dˉ=2(cw1fw−cb1κ2ft2)ν~2d3 Qˉrˉ=dfwdg dgdr fˉw,ν~ˉ+=rˉκ2d2S~,S~ˉ–=r rˉS~,dˉ–=2r rˉdBˉ=FB S~ˉ,Ωˉ=FΩ S~ˉ,ν~ˉ+=fv2κ2d2 Bˉ,fˉv2=ν~κ2d2 Bˉ,dˉ–=2Bd BˉGˉv,x+=sgn⁡(ω) Ωˉ,Gˉu,y–=sgn⁡(ω) Ωˉ,χˉ=ft2′ fˉt2+fv2′ fˉv2ν~ˉ+=χˉν,νˉ–=χ χˉν,ρˉ–=ν νˉρ,Tˉ+=μTρ νˉ

r 被截断时它是常数 10,这一处的 rˉ 不往下传。每个输入收集了几份:ν̃ 经 a、Q、r、B、χ 五处,d 经 Q、r、B 三处(第 12 节把 dˉ 经壁面距离交给坐标)。前向第十一步里 −ρQ 对 ρ 的导数是 −Q − ρ∂Q/∂ρ,在这里就是第一行的 −Qsˉ 与经 χ、ν 回来的那一份。

Where r is capped it is the constant 10 and its rˉ goes no further. The shares each input collects: ν̃ through a, Q, r, B and χ, five places; d through Q, r and B, three (Section 12 hands dˉ on to the coordinates through the wall distance). The −Q − ρ∂Q/∂ρ of the forward Step 11 is here the −Qsˉ of the first line plus the share that comes back through χ and ν.

核对:在本页 48 个内部面上,粘性核的伴随语句与它的前向语句满足点积恒等式,最大差 2.4×10−16(相对各乘积的绝对值之和),与 viscous() 局部磁带的反向扫描相差 3.7×10−16;在求源项的 11 个控制体上,SA 源项的伴随语句与前向语句 3.6×10−16,与 source() 的磁带 2.7×10−15;原始变量的 ΠT 与 Π 2.7×10−16(本页代码在构建时计算)。

Check: on the 48 interior faces of this page the viscous kernel's adjoint and tangent statements satisfy the dot-product identity to 2.4×10−16 (relative to the sum of the products' sizes) and agree with a reverse sweep of viscous()'s local tape to 3.7×10−16; in the 11 control volumes where the source is evaluated the SA source's adjoint and tangent statements to 3.6×10−16 and source()'s tape to 2.7×10−15; the primitives' ΠT and Π to 2.7×10−16 (computed by this page's code at build time).

逐步推导:壁面行、来流行与出口半面

Step by step: the wall rows, the inflow rows and the outlet half-faces

壁面节点。壁面半面不调用任何核(第 4 节);节点的 ρu、ρv、ρν̃ 三行被替换成 U 本身。前向 R˙i,k←U˙i,k;伴随先于一切 Uˉi,k+=Rˉi,k、Rˉi,k←0:循环在这些分量上看到零,只在 ρ 与 ρE 上看到原来的权重。目标函数的 g 例外:它的种子 −eD/q∞ 正放在替换之前的动量行上(第 7 节),所以不做这一步。

The wall nodes. A wall half-face calls no kernel (Section 4); the node's ρu, ρv and ρν̃ rows are replaced by U itself. Tangent R˙i,k←U˙i,k; adjoint, before everything else, Uˉi,k+=Rˉi,k and Rˉi,k←0: the loops see zero in these components and the original weights only in ρ and ρE. The objective's g is the exception: its seed −eD/q∞ sits on the momentum rows before the replacement (Section 7), so it skips this step.

来流节点。本页的残差在来流节点与来流半面上用原来的处理(第 4 节);伴随一致的版本用另一种,下面把两种一并写出,好对照。原来的处理替换 ρ、ρu、ρv、ρν̃ 四行:

The inflow nodes. This page's own residual takes the original treatment on the inflow nodes and half-faces (Section 4); the adjoint-consistent version takes the other, and both are written out below for comparison. The original treatment replaces the ρ, ρu, ρv and ρν̃ rows:

Ri,k←Ui,k−U∞,k(k=ρ,ρu,ρv,ρν~),Uˉi,k+=Rˉi,k,Rˉi,k←0

伴随一致的处理只替换三行,能量行先减去 u∞ 乘两行动量行:

The adjoint-consistent treatment replaces three rows, and the energy row first subtracts u∞ times the two momentum rows:

Ri,ρE–=u∞⋅Ri,ρ𝐮,Ri,k←Ui,k−Ui,ρW∞,k(k=ρu,ρv,ρν~)Uˉi,k+=Rˉi,k,Uˉi,ρ–=W∞,k Rˉi,k,Rˉi,k←0;Rˉi,ρ𝐮–=u∞ Rˉi,ρE

原来的处理转置后,循环在来流节点上只看到 (0, 0, 0, ψρE, 0):离散伴随在那里满足 λρ = 0、β = 0、φ = 0(附录 B.3),而连续伴随要的是 β + ζu = 0、φ = 0,λρ 不受约束(附录 B.2)。伴随一致的处理转置后,循环看到 (ψρ, −u∞ψρE, −v∞ψρE, ψρE, 0):动量分量加上 u∞ 乘能量分量恰为零,这一行就是离散的 β + ζu = 0(附录 B.4),而质量分量 ψρ 不受约束。来流半面的通量,原来的处理是本节点状态的对流通量减去本节点梯度给出的粘性通量(第 4 遍后只剩能量行),伴随一致的处理是 F(Wbc)·n,Wbc = (ρ∞, u∞, v∞, Ti, ν̃∞),它的前向与伴随语句是

After the original treatment's transpose the loops see only (0, 0, 0, ψρE, 0) at an inflow node: the discrete adjoint satisfies λρ = 0, β = 0 and φ = 0 there (Appendix B.3), while the continuous adjoint needs β + ζu = 0 and φ = 0 and leaves λρ free (Appendix B.2). After the adjoint-consistent treatment's transpose the loops see (ψρ, −u∞ψρE, −v∞ψρE, ψρE, 0): the momentum components plus u∞ times the energy component are exactly zero, so this row is the discrete β + ζu = 0 (Appendix B.4), and the mass component ψρ is left free. The inflow half-face's flux is, in the original treatment, the node state's convective flux minus the viscous flux of the node's gradients (only its energy row survives pass 4), and in the adjoint-consistent one F(Wbc)·n with Wbc = (ρ∞, u∞, v∞, Ti, ν̃∞), whose tangent and adjoint statements are

Φ˙=T˙i ρ∞(0, nx, ny, cp u∞⋅n, 0),Tˉi+=ρ∞(n⋅Φˉρ𝐮+cp (u∞⋅n) ΦˉρE)

图 9.6 把两种处理在本页每个来流节点上的这些数并排画出来。出口半面:本节点状态的物理通量,压力换成 p∞,Φ = ρq(1, u, v, E, ν̃) + p∞(0, nx, ny, q, 0);它的前向与伴随语句与 Roe 核 (1)、(2) 在一侧的那几句相同,只是 H 换成 E、压力换成常数 p∞,能量分量多一项 p∞q(前向 p∞q˙)。

Figure 9.6 draws these numbers for both treatments, side by side, at every inflow node of this page. The outlet half-face: the node state's physical flux with the pressure replaced by p∞, Φ = ρq(1, u, v, E, ν̃) + p∞(0, nx, ny, q, 0); its tangent and adjoint statements are those of the Roe kernel's one-side statements (1) and (2), with H replaced by E, the pressure by the constant p∞, and the extra energy term p∞q (tangent p∞q˙).

(a) 原来的处理(本页)(a) original (this page)ρρuρvρEρν̃|动量+u∞能量||mom.+u∞E|循环看到的 ¯Rwhat the loops see of ¯Rn19 90°000−9.6402.28n20 135°000−26.106.18n21 180°000−32.607.72n22 225°000−28.006.62n23 270°000−11.802.80循环只看到 (0, 0, 0, ψρE, 0)the loops see (0, 0, 0, ψρE, 0) only最后一列 = |u∞ψρE| ≠ 0last column = |u∞ψρE| ≠ 0(b) 伴随一致的处理(b) adjoint-consistentρρuρvρEρν̃|动量+u∞能量||mom.+u∞E|循环看到的 ¯Rwhat the loops see of ¯Rn19 90°67.44.990.44−21.200n20 135°−323.0−8.54−0.7536.200n21 180°1117.250.94.45−215.700n22 225°−306.3−7.50−0.6631.800n23 270°110.87.180.63−30.500循环看到 (ψρ, −u∞ψρE, −v∞ψρE, ψρE, 0)the loops see (ψρ, −u∞ψρE, −v∞ψρE, ψρE, 0)最后一列恰为 0:离散的 β + ζu = 0last column exactly 0: the discrete β + ζu = 0
图 9.6 · 两种来流处理在本页每个来流节点上的伴随行,各在自己的收敛解上(节点名后是它的方位角);标着“本页”的一格是本页自己的残差,另一格取自同一格式的另一页的解。每一格是第 4 遍反向之后面循环看到的 Rˉ 的一个分量,蓝为正、紫为负,每列一个色标;最后一列是动量分量加 u∞ 乘能量分量的大小 ∣β^+ζ^u∞∣。(a) 原来的处理把 ρ、ρu、ρv、ρν̃ 四行替换成 U − U∞,循环只看到能量分量,所以 β^+ζ^u∞=u∞ψρE≠0:离散伴随在来流上满足 λρ = 0、β = 0、φ = 0(附录 B.3)。(b) 伴随一致的处理先从能量行减去 u∞ 乘两行动量行,再替换三行:循环看到的动量分量正好是 −u∞ 乘能量分量,最后一列在每个节点上都是精确的 0,这就是离散的 β + ζu = 0(附录 B.4);质量分量 ψρ 不受约束(u∞ = (0.236, 0.021))。Figure 9.6 · The inflow's adjoint rows of the two far-field treatments at every inflow node of this page, each at its own converged solution (the node's name is followed by its angle); the panel marked “this page” is this page's own residual, and the other is computed at the solution of the other page of this scheme. Each cell is one component of the Rˉ the face loops see after pass 4 reversed, blue positive and violet negative, one colour scale per column; the last column is the size of the momentum components plus u∞ times the energy component, ∣β^+ζ^u∞∣. (a) The original treatment replaces the ρ, ρu, ρv and ρν̃ rows by U − U∞, and the loops see the energy component only, so β^+ζ^u∞=u∞ψρE≠0: on the inflow the discrete adjoint satisfies λρ = 0, β = 0 and φ = 0 (Appendix B.3). (b) The adjoint-consistent treatment first subtracts u∞ times the two momentum rows from the energy row and then replaces three rows: the momentum components the loops see are exactly −u∞ times the energy component, and the last column is exactly 0 at every node, the discrete β + ζu = 0 (Appendix B.4); the mass component ψρ is left free (u∞ = (0.236, 0.021)).

核对:来流半面 8 个、出口半面 8 个:这些伴随语句与前向语句的点积恒等式最大差 3.6×10−16,与 core.js 面核的局部磁带 JfT 相差 3.9×10−16;两种来流处理的核在本页状态上满足点积恒等式到 4.2×10−16。带强边界行的整个伴随那一遍与 core.js 的 applyAT 相差 1.4×10−15,去掉第 4 遍的版本(g 用的那个)相差 6.6×10−16;图中两种处理的行另经 core.js 核对(ATψ 等于被替换行交给 Uˉ 的那一份加上各遍对循环所见权重的转置)到 0(本页代码在构建时计算)。

Check: 8 inflow and 8 outlet half-faces: these adjoint statements and the tangent ones satisfy the dot-product identity to 3.6×10−16 and agree with the local tapes of core.js's face kernels, JfT, to 3.9×10−16; both inflow treatments' kernels at this page's state satisfy the identity to 4.2×10−16. The whole adjoint pass with its strong rows agrees with core.js's applyAT to 1.4×10−15, and without pass 4 (the version g uses) to 6.6×10−16; the figure's rows of both treatments are checked against core.js too (ATψ equals the replaced rows' share of Uˉ plus the passes transposed on the weights the loops see) to 0 (computed by this page's code at build time).

算例:一个内部对偶面、一个壁面节点、一个来流节点

A worked example: one interior dual face, one wall node, one inflow node

用本页的数把上面的语句走一遍。前向的种子取第 10 节的前向解,U˙=v(v 是第 10 节的那个向量,不是速度分量 v;迎角方向,α˙=1;前向在第 82 次迭代满足判据),伴随的种子取第 11 节的伴随解,Rˉ=ψ。

The statements above, walked through with this page's numbers. The tangent's seed is Section 10's tangent solution, U˙=v (v is that vector, not the velocity component v; along the angle of attack, α˙=1; the tangent meets its criterion at iteration 82), and the adjoint's seed is Section 11's adjoint, Rˉ=ψ.

内部面 e17(L = n9,R = n10;图 2.2 里的那个面)。两侧的原始变量、它们的前向导数,以及这个面的反向语句加给它们的伴随份额 JfTΦˉf:

The interior face e17 (L = n9, R = n10; the face of Figure 2.2). The two sides' primitives, their tangents, and the shares of their adjoints this face's reverse statements add, JfTΦˉf:

分量componentWLWRW˙LW˙RWˉLWˉR
ρ0.60340.63980.021080.0299220.9912.26
u0.060820.6386−0.02173−0.279−10.78.238
v−0.002428−0.18780.07260.094786.141−1.151
T1.7751.558−0.1022−0.08157.2473.951
ν̃0.0081940.02056−0.002801−0.0050040.002351−0.005969

面上的通量,它的前向导数(Roe 部分与粘性部分)与种子 Φˉ=ψL−ψR:

The face's flux, its tangent (the Roe part and the viscous part), and the seed Φˉ=ψL−ψR:

分量componentΦΦ˙roe−Φ˙viscΦ˙Φˉ
ρ−0.11450.0570900.0570926.85
ρu−0.49060.054291.730×10−40.05446−48.19
ρv0.3191−0.01064−0.00509−0.015733.537
ρE−0.69080.38150.0025690.38413.754
ρν̃−0.0010420.00107−3.293×10−60.0010660.05398

这个面上的局部对偶恒等式:两边都是 30 个输入对 5 个输出的同一个双线性型(右边依次是 WL、WR、GL、GR 四组输入的份额)。

The local duality identity on this face: both sides are the same bilinear form of 30 inputs against 5 outputs (on the right, the shares of the four groups of inputs WL, WR, GL, GR).

ΦˉTΦ˙=0.294794859943873,WˉLTW˙L+WˉRTW˙R+GˉLTG˙L+GˉRTG˙R=0.380267−2.36254+1.74066+0.536416=0.294794859943872

壁面节点 n1。它的 ρu、ρv、ρν̃ 三行被替换,所以前向解 U˙i 在这三个分量上为零;伴随的第 4 遍反向把 ψ 在这三行上的值交给 Uˉ,循环只看到 ρ 与 ρE 上的权重:

The wall node n1. Its ρu, ρv and ρν̃ rows are replaced, so the tangent solution U˙i is zero in these three components; pass 4 reversed hands ψ's values in these rows to Uˉ, and the loops see weights only in ρ and ρE:

分量componentU˙iRˉi=ψi第 4 遍交给 Uˉipass 4 to Uˉi循环看到的 RˉiRˉi the loops see
ρ0.0463329.86029.86
ρu0−1.884−1.8840
ρv0−1.127−1.1270
ρE0.1027−0.1080−0.108
ρν̃0−9.935×10−4−9.935×10−40

来流节点 n21(方位 180°,两种处理各在自己的收敛解上)。本页自己的解用原来的处理,“原来”的两栏就是本页的 ψ 与循环看到的权重;另两栏取自另一页(伴随一致的版本)的解。ψ 在五行上的值与第 4 遍反向之后循环看到的权重:

The inflow node n21 (at 180°, each treatment at its own converged solution). This page's own solution uses the original treatment, so the “original” columns are this page's own ψ and the weights its loops see; the other two columns come from the solution of the adjoint-consistent version. ψ's values in the five rows and the weights the loops see after pass 4 reversed:

分量component原来的 ψioriginal ψi原来:循环看到original: loops see一致的 ψiconsistent ψi一致:循环看到consistent: loops see
ρ39.44011171117
ρu−238.4051.2250.86
ρv1.876012.754.45
ρE−32.6−32.6−215.7−215.7
ρν̃−0.180104.0980

把循环看到的动量分量记作 β^、能量分量记作 ζ^,两种处理的 β^+ζ^u∞:

Writing the momentum components the loops see as β^ and the energy component as ζ^, the two treatments' β^+ζ^u∞:

(a)  β^+ζ^ u∞=(−7.68617, −0.672453),(b)  β^+ζ^ u∞=(0, 0)

(a) 是原来的处理:循环在动量分量上看到零,β^+ζ^u∞ 就是 u∞ψρE,不为零。(b) 是伴随一致的处理:它是精确的零(u∞ = (0.2357, 0.02062))。

(a) is the original treatment: the loops see zero in the momentum components, so β^+ζ^u∞ is u∞ψρE, not zero. (b) is the adjoint-consistent one: it is exactly zero (u∞ = (0.2357, 0.02062)).

核对:上面的前向与伴随值由 kernels_ad.js 的语句算出;用 core.js 面核的局部磁带另算一遍(Jf 乘输入的点、JfT 乘 Φˉ),两者最大相对差 4.2×10−16;内部面上对偶恒等式两边相差 9.0×10−17(相对各乘积的绝对值之和)(本页代码在构建时计算)。

Check: the tangent and adjoint values above come from the statements of kernels_ad.js; recomputed from the local tapes of core.js's face kernels (Jf times the inputs' dots, JfT times Φˉ) they differ by at most 4.2×10−16 (relative); the two sides of the duality identity on the interior face differ by 9.0×10−17 (relative to the sum of the products' sizes) (computed by this page's code at build time).

图 9.7 把伴随的各遍放到网格上倒着执行,种子取第 11 节的伴随解,Rˉ=ψ(第 4 遍反向先把被替换行的权重交给 Uˉ)。面倒着一个接一个,每个面把 JfTΦˉf 累加到两侧;每个控制体上画的是它五个分量 Wˉ=(ρˉ,uˉ,vˉ,Tˉ,ν~ˉ) 的累加值,ν~ˉ 就是 SA 变量的伴随。梯度的权重经 ΓT 回到模板,最后经 ΠT 得到 Uˉ=ATψ=−g:伴随方程在每个控制体上成立,精确到求解停下时的残差:判据(残差的 RMS 小于 10−13)在第 95 次迭代首次满足,本页用的是最后一步(第 118 次)迭代,它的 RMS 是 6.7×10−15,单个分量的残差最大 4.0×10−14,所以扫描在每个控制体上留下的就是那里的 −g,差不超过这个残差;在本页这套粗网格上,目标经壁面的对偶面与它们的最小二乘模板读到全部 24 个控制体,g 处处不为零。

Figure 9.7 runs the adjoint's passes backwards on the mesh, with Section 11's adjoint as the seed, Rˉ=ψ (pass 4 reversed first hands the replaced rows' weights to Uˉ). The faces go one after another in reverse, each accumulating JfTΦˉf into its two sides; every control volume shows the accumulated values of its five components Wˉ=(ρˉ,uˉ,vˉ,Tˉ,ν~ˉ), and ν~ˉ is the adjoint of the SA variable. The gradients' weights go back to their stencils through ΓT, and finally ΠT gives Uˉ=ATψ=−g: the adjoint equation holds in every control volume to the residual the solve stopped at: the criterion (an RMS residual below 10−13) was first met at iteration 95, the page uses the last iterate (iteration 118), whose RMS residual is 6.7×10−15 with a largest single entry of 4.0×10−14, so what the sweep leaves in each control volume is its −g to within that residual; on this page's coarse mesh the objective reads all 24 control volumes through the wall's dual faces and their least-squares stencils, so g is non-zero everywhere.

图 9.7Figure 9.7
第 10 节Section 10

前向求解:A v = −f

The forward solve: A v = −f

前向方程用原始迭代的同一个 K 求解:

The tangent equation is solved with the same K as the primal iteration:

vk+1=vk−K (Avk+f),v0=0

K 是 U* 处的两次对称 Gauss–Seidel(CFL 固定在 200),A v 是第 8 节的 residual_d 取 U_d = v。原始迭代在接近 U* 时的误差也按 I − KA 传播,所以两者的渐近速率相同,都是迭代矩阵 I − KA 的谱半径:二阶格式 ρ(I − KA) = 0.712(把 I − KA 装配成 120 × 120 的稠密矩阵,取它全部特征值的最大模;最大的是实特征值)。在残差从初值的 10−4 降到 10−11 的区间里拟合的每步因子是:原始 0.720、前向 0.722,与 ρ(I − KA) 的相对差 +1.1%、+1.4%。拟合区间有限,残差在其中并不是严格的等比数列,所以拟合值可以略高或略低于 ρ(I − KA)。f = ∂R/∂D:迎角与马赫数只进入来流数据 u∞ = M√γ(cos α, sin α)(出口的 p∞ = 1 与它们无关);μref 进入 μ(T)、来流的 ν̃∞ = 3μref,以及所有粘性与源项。

K is two symmetric Gauss–Seidel sweeps at U* (with the CFL number fixed at 200), and A v is Section 8's residual_d with U_d = v. Near U* the primal iteration's error also propagates by I − KA, so the two share the same asymptotic rate, the spectral radius of the iteration matrix I − KA: ρ(I − KA) = 0.712 for the second-order scheme (the largest modulus among all the eigenvalues of the dense 120 × 120 matrix I − KA; the largest is real). Fitted over the band where each residual falls from 10−4 to 10−11 of its start, the factors per iteration are 0.720 (primal) and 0.722 (tangent), +1.1% and +1.4% from ρ(I − KA). Over a finite band the residual is not an exact geometric sequence, so a fitted factor can lie a little above or below ρ(I − KA). f = ∂R/∂D: the angle of attack and the Mach number enter only the inflow data u∞ = M√γ(cos α, sin α) (the outlet's p∞ = 1 does not depend on them); μref enters μ(T), the inflow's ν̃∞ = 3μref, and every viscous and source term.

图 10.1Figure 10.1

结果:二阶格式 dCD/dα = −15.57802477、dCD/dM = −45.100884、dCD/dμref = 620.99019。它们与第 11 节伴随给出的值相对差 5.5×10−16(除以 |∂CD/∂D|、|ψTf| 与 |dCD/dD| 中最大的一个,见下);直接除以导数本身是 5.0×10−15。

The result: for the second-order scheme dCD/dα = −15.57802477, dCD/dM = −45.100884, dCD/dμref = 620.99019. They differ from the adjoint's values of Section 11 by a relative 5.5×10−16 (over the largest of |∂CD/∂D|, |ψTf| and |dCD/dD|, see below); over the derivative itself the difference is 5.0×10−15.

本页比较流动参数的导数时,相对差默认除以三个量中最大的一个:显式部分 |∂CD/∂D|、伴随部分 |ψTf|(等于前向的 |gTv|)与导数本身 |dCD/dD|。本页 dCD/dM = ∂CD/∂M + ψTf = −542.003 + 496.902 = −45.1009:两部分几乎抵消,和只有较大部分的 1/12。舍入误差随两部分的大小走,不随它们的和走,所以除以和会把它放大约 12 倍;按两部分归一量的是舍入误差真正所在的量级。第 11、13、14 节与各演示用同一个归一,并同时给出除以导数本身的值;坐标导数没有两部分之分,直接除以导数本身(或按范数,见第 14 节)。

When this page compares derivatives with respect to the flow parameters, a relative difference is by default divided by the largest of three sizes: the explicit part |∂CD/∂D|, the adjoint part |ψTf| (equal to the tangent's |gTv|) and the derivative itself |dCD/dD|. On this page dCD/dM = ∂CD/∂M + ψTf = −542.003 + 496.902 = −45.1009: the two parts nearly cancel, and the sum is 1/12 of the larger part. Round-off scales with the parts, not with their sum, so dividing by the sum inflates it about 12 times; normalising by the parts measures it at the size where it actually lives. Sections 11, 13 and 14 and the demos use the same normalisation and also give the difference over the derivative itself; the coordinate derivatives have no such parts and are divided by the derivative itself (or taken normwise, Section 14).

第 11 节Section 11

伴随求解:ATψ = −g

The adjoint solve: ATψ = −g

ψk+1=ψk−KT (ATψk+g),ψ0=0

KT 不需要另外编程:在 PT 上做同样的对称扫描,正好就是 K 的转置。把 P 按控制体编号分成块对角 diag(P)、严格下三角 P< 与严格上三角 P>。从零开始的一次对称扫描(前扫接回扫)是线性算子 K1:前扫解 (diag(P) + P<)x' = b,回扫解 (diag(P) + P>)x = b − P<x',合起来

KT needs no separate code: the same symmetric sweeps on PT are exactly the transpose of K. Split P, in the numbering of the control volumes, into its block diagonal diag(P), its strictly lower block triangle P< and its strictly upper block triangle P>. One symmetric sweep from zero (forward then backward) is a linear operator K1: the forward pass solves (diag(P) + P<)x' = b, the backward pass (diag(P) + P>)x = b − P<x', and together

K1(P)=(diag⁡(P)+P>)−1diag⁡(P) (diag⁡(P)+P<)−1,K1(P)T=(diag⁡(P)T+P<T)−1diag⁡(P)T(diag⁡(P)T+P>T)−1=K1(PT)

因为 PT 的块对角是 diag(P)T、严格下三角是 P>T、严格上三角是 P<T。本页的 K 是两次扫描:第二次从第一次的结果 x1 = K1b 出发,x2 = x1 + K1(b − Px1),所以

since the block diagonal of PT is diag(P)T, its strictly lower triangle P>T and its strictly upper triangle P<T. This page's K is two sweeps: the second starts from the first one's result x1 = K1b, x2 = x1 + K1(b − Px1), so

K=2K1−K1PK1,KT=2K1T−K1TPTK1T=2K1(PT)−K1(PT) PT K1(PT)

这正是在 PT 上做两次同样的对称扫描(扫描次数更多时同理:k 次扫描是 Σj<k(I − K1P)jK1,它的转置是 PT 上的同一个和)。代码里 precond(P, b, 2, transposed) 正是这样:transposed 时每个对角块与邻居块都取转置,扫描顺序不变。二阶格式随机向量上 ⟨a, Kb⟩ 与 ⟨KTa, b⟩ 的相对差 4.2×10−16(构建时测得)。于是伴随迭代与前向迭代在每一步都给出同一个导数估计:从零开始,

That is exactly two of the same symmetric sweeps on PT (and so for any number of sweeps: k sweeps are Σj<k(I − K1P)jK1, whose transpose is the same sum on PT). The code precond(P, b, 2, transposed) does just that: transposed, every diagonal and neighbour block is transposed and the sweep order stays. On random vectors ⟨a, Kb⟩ and ⟨KTa, b⟩ differ by a relative 4.2×10−16 for the second-order scheme (measured at build time). So the adjoint and the tangent iterations give the same derivative estimate at every iteration: started from zero,

gTvk=−∑j<kgT(I−KA)jKf=−∑j<kgTK(I−AK)jf=(ψk)Tf

下面的动画逐行执行一次 K 与一次 KT:两边解的行顺序相同,用到的块位置也相同,只是 PT 的第 i 行取的是 P 的第 i 列、每块转置;表里是前几步的两个导数估计。

The animation below executes one K and one KT row by row: both solve the rows in the same order and use blocks at the same places, except that row i of PT takes column i of P, every block transposed; the table gives the two derivative estimates over the first iterations.

图 11.1Figure 11.1

二阶格式的实测:两者在所有迭代上的最大相对差 2.3×10−15(按第 10 节的归一;除以导数本身是 2.3×10−15)。伴随在第 95 次迭代满足判据,同一区间拟合的每步因子 0.717(与 ρ(I − KA) 相差 +0.74%)。三个迭代(原始、前向、伴随)的渐近速率都是 ρ(I − KA) = 0.712:伴随的迭代矩阵 I − KTAT 是 I − AK 的转置,而 I − AK 与 I − KA 的谱相同。第 16 节把这个不动点迭代与 GMRES、直接 LU 分解放在一起比较。

Measured for the second-order scheme: the largest relative difference over all iterations is 2.3×10−15 (in the normalisation of Section 10; over the derivative itself 2.3×10−15). The adjoint meets its criterion at iteration 95, with a fitted factor of 0.717 over the same band (+0.74% from ρ(I − KA)). The three iterations (primal, tangent, adjoint) share the asymptotic rate ρ(I − KA) = 0.712: the adjoint's iteration matrix I − KTAT is the transpose of I − AK, and I − AK has the spectrum of I − KA. Section 16 compares this fixed point with GMRES and a direct LU factorisation.

图 11.2Figure 11.2

ψ 的每个分量是对应方程残差的灵敏度:把某个控制体某个方程的残差加上一个小量 ε(Rk → Rk + ε),CD 改变 ψkε。壁面节点被替换的行是 R = ρu − (ρu)w,边界值 (ρu)w = 0:边界值加 ε 等于残差减 ε,所以这些分量的 −ψ 就是 CD 对壁面动量边界值的灵敏度。来流节点的四行 R = U − U∞ 也一样:−ψ 是 CD 对来流边界值的灵敏度,在附录 A 的连续伴随里,它对应来流边界上的那几项。

Each component of ψ is the sensitivity to the residual of its equation: adding a small ε to the residual of one equation of one control volume (Rk → Rk + ε) changes CD by ψkε. A wall node's replaced row is R = ρu − (ρu)w with the boundary value (ρu)w = 0: raising the boundary value by ε lowers the residual by ε, so −ψ of these components is the sensitivity of CD to the wall's momentum boundary value. The same holds for an inflow node's four rows R = U − U∞: −ψ is the sensitivity of CD to the inflow boundary values, which the continuous adjoint of Appendix A carries in its inflow boundary terms.

下面的动画把两个迭代放在一起:左边是原始的伪时间迭代从来流状态走向 U*,右边是伴随迭代从 ψ = 0 走向 ψ。伴随迭代用 U* 处的 P;原始迭代每步在当前状态重新组装 P,CFL 从 5 放大到上限 200。接近 U* 时两者的 P 相同,误差按同一个速率 ρ(I − KA) 衰减,残差曲线的斜率也就相同。

The animation below runs the two iterations side by side: on the left the primal pseudo-time iteration moves from the free stream to U*, on the right the adjoint iteration moves from ψ = 0 to ψ. The adjoint iteration uses the P at U*; the primal one reassembles P at the current state every step, with the CFL number growing from 5 to its cap of 200. Near U* the two use the same P, their errors decay at the same rate ρ(I − KA), and the residual curves have the same slope.

图 11.3Figure 11.3

收敛后的 ψ 五个分量同时画在图 11.4 里(上面的演示一次只看一个)。

The five components of the converged ψ are drawn side by side in Figure 11.4 (the demo above shows one at a time).

ψρ−154.30154.3ψρu−69.25069.25ψρv−42.58042.58ψρE−32.60032.60ψρν̃−0.37800.378红:正 紫:负 颜色深浅按各分量自己的最大值red: positive · violet: negative · shaded by each component's own largest value灰:被替换的行(它们的 ψ 是反作用,不是场值)grey: replaced rows (their ψ is a reaction, not a field value)
图 11.4 · 收敛的伴随 ψ(二阶格式,ATψ = −g 的解)的五个分量,每个分量用自己的色标。ψ 的第 k 个分量是 CD 对该控制体第 k 个方程残差的灵敏度:它大的地方,这个残差的误差对阻力影响大。壁面节点的 ρu、ρv、ρν̃ 分量与来流节点被替换的分量不画(灰色):它们是反作用,不是场值。Figure 11.4 · The five components of the converged adjoint ψ (second order, the solution of ATψ = −g), each on its own colour scale. Component k of ψ is the sensitivity of CD to the residual of equation k in that control volume: where it is large, an error in that residual matters for the drag. The ρu, ρv and ρν̃ components of the wall nodes and the replaced components of the inflow nodes are not drawn (grey): they are reactions, not field values.

逐步推导:一次对称扫描为什么是 x + K1(b − Px)

Step by step: why one symmetric sweep is x + K1(b − Px)

上面用了“第二次扫描从 x1 出发得到 x1 + K1(b − Px1)”。它对任何起点 x 都成立,推导如下。

Above, the second sweep from x1 was taken to give x1 + K1(b − Px1). This holds from any starting point x; here is why.

第一步,前扫。第 i 行用前面已经更新的值与后面的旧值,(diag(P) + P<)x′ = b − P>x。两边减去 (diag(P) + P<)x:

Step 1, the forward pass. Row i uses the values already updated before it and the old values after it, (diag(P) + P<)x′ = b − P>x. Subtract (diag(P) + P<)x from both sides:

(diag⁡(P)+P<)(x′−x)=b−(P<+diag⁡(P)+P>) x=b−Px⟹x′=x+(diag⁡(P)+P<)−1(b−Px)

第二步,回扫。同理 (diag(P) + P>)x″ = b − P<x′ 给 x″ = x′ + (diag(P) + P>)−1(b − Px′)。

Step 2, the backward pass. In the same way (diag(P) + P>)x″ = b − P<x′ gives x″ = x′ + (diag(P) + P>)−1(b − Px′).

第三步,合起来。由第一步,b − Px′ = (I − P(diag(P) + P<)−1)(b − Px);再把 I 写成 (diag(P) + P<)(diag(P) + P<)−1,并用 P = P< + diag(P) + P>:

Step 3, combine. By Step 1, b − Px′ = (I − P(diag(P) + P<)−1)(b − Px); write I as (diag(P) + P<)(diag(P) + P<)−1 and use P = P< + diag(P) + P>:

x′′−x=[(diag⁡(P)+P<)−1+(diag⁡(P)+P>)−1(I−P(diag⁡(P)+P<)−1)](b−Px)=(diag⁡(P)+P>)−1[(diag⁡(P)+P>)+(diag⁡(P)+P<)−P](diag⁡(P)+P<)−1(b−Px)=(diag⁡(P)+P>)−1diag⁡(P) (diag⁡(P)+P<)−1(b−Px)=K1 (b−Px)

第四步,两次扫描与转置。从 x = 0 出发,x1 = K1b,x2 = x1 + K1(b − Px1) = (2K1 − K1PK1)b = Kb。转置把三个因子倒过来:K1T = (diag(P)T + P<T)−1diag(P)T(diag(P)T + P>T)−1,最右边、最先作用的 diag(P)T + P>T 正是 PT 的块对角加严格下三角:PT 上仍是先前扫、再回扫,上面的动画一行一行地演示了这一点。

Step 4, two sweeps and the transpose. From x = 0, x1 = K1b and x2 = x1 + K1(b − Px1) = (2K1 − K1PK1)b = Kb. Transposing reverses the three factors: K1T = (diag(P)T + P<T)−1diag(P)T(diag(P)T + P>T)−1, and the rightmost factor, applied first, diag(P)T + P>T, is exactly the block diagonal plus the strictly lower triangle of PT: on PT it is still a forward pass first and a backward pass second, which the animation above shows row by row.

核对:把本页的 P 写成 120×120 的稠密矩阵,由它算出的 2K1 − K1PK1 与代码的 K(对 120 个单位向量各做一次 precond)相差 7.4×10−16;transposed 扫描得到的矩阵与 KT 相差 1.5×10−16;从随机的 x 做一次扫描,与 x + K1(b − Px) 相差 1.5×10−15(都相对最大元)(本页代码在构建时计算)。

Check: with this page's P written as a dense 120×120 matrix, the 2K1 − K1PK1 computed from it and the code's K (one precond per unit vector, 120 of them) differ by 7.4×10−16; the matrix of the transposed sweeps and KT differ by 1.5×10−16; one sweep from a random x and x + K1(b − Px) differ by 1.5×10−15 (all relative to the largest entry) (computed by this page's code at build time).

第 12 节Section 12

几何导数:dCD/dX

Geometric derivatives: dCD/dX

dCDdX=∂CD∂X+ψT∂R∂X
X (48)nfxfxi, ΔxVi最小二乘权重LSQ weightsdi(壁面距离)di (wall distance)R, CDψT​∂R/∂XψT​∂R/∂X+ ∂CD/∂X+ ∂CD/∂X
图 12.1 · 节点坐标经六类几何量进入残差与目标:面法向、面点(重构沿 xf − xi 外推)、中心与连线 Δx、体积、最小二乘权重、壁面距离。坐标导数就是把 ψ 与目标的权重沿这些箭头反向送回 X:本页把固定 U* 下的整个残差录成一条磁带来完成。Figure 12.1 · The node coordinates enter the residual and the objective through six kinds of geometric quantity: face normals, face points (the reconstruction extrapolates along xf − xi), centres and the lines Δx, volumes, least-squares weights, and wall distances. The coordinate derivative sends the weights of ψ and of the objective back along these arrows to X: this page does it with one tape of the whole residual at fixed U*.

坐标经几何量进入残差:面法向 n、面点 xf(重构沿 xf − xi 外推)、中心与连线 Δx、体积 V、最小二乘权重(依赖中心位置)、壁面距离(依赖中心与最近的壁面边)。ψT∂R/∂X 是固定 U* 时对残差的一次反向扫描:本页把几何那一遍也写在同一套运算上,录一条包括几何的磁带(31267 个节点),用 ψ 作种子(Rˉ=ψ)反向扫一次,得到 Xˉ=(∂R/∂X)Tψ 与三个流动参数的 Dˉ=(∂R/∂D)Tψ;同一条磁带以 CˉD=1 再扫一次给出显式部分,两者之和就是全部 48 个坐标与 3 个流动参数的导数。

The coordinates enter the residual through the geometry: the face normals n, the face points xf (the reconstruction extrapolates along xf − xi), the centres and the lines Δx, the volumes V, the least-squares weights (which depend on the centres), and the wall distances (on the centre and the nearest wall edge). ψT∂R/∂X is one reverse sweep of the residual at fixed U*: this page writes the geometric pass on the same arithmetic, tapes the residual including the geometry (31267 nodes) and sweeps it backwards once with ψ as the seed (Rˉ=ψ), which gives Xˉ=(∂R/∂X)Tψ and, for the three flow parameters, Dˉ=(∂R/∂D)Tψ; one more sweep of the same tape with CˉD=1 gives the explicit parts, and the two sums are the derivatives for all 48 coordinates and the 3 flow parameters.

不会失败的结构检验

Structural checks that cannot fail

三个恒等式只依赖离散格式的不变性,与流动无关(这里都是全导数 d):整体平移不改变任何东西,ΣidCD/dxi = ΣidCD/dyi = 0;整体旋转等价于反向转动来流,Σi(xidCD/dyi − yidCD/dxi) = −dCD/dα;长度与 μref 同时放大同一个倍数,CD(以固定参考长度 1 归一)也放大同一个倍数,ΣX·dCD/dX + μrefdCD/dμref = CD。构建页面时在 Node.js 里测得的残差:平移 2.3×10−14、旋转 7.1×10−15、伸缩 4.3×10−14;下面演示里的表是你的浏览器重算的,舍入误差不同,末位会不一样,但都在 10−13 以下。

Three identities depend only on the invariances of the discrete scheme, not on the flow (all total derivatives d here): a rigid translation changes nothing, ΣidCD/dxi = ΣidCD/dyi = 0; a rigid rotation is the same as turning the free stream the other way, Σi(xidCD/dyi − yidCD/dxi) = −dCD/dα; scaling the lengths and μref together by the same factor scales CD (normalised by the fixed reference length 1) by that factor, ΣX·dCD/dX + μrefdCD/dμref = CD. The residuals measured in Node.js when the page was built: translation 2.3×10−14, rotation 7.1×10−15, scaling 4.3×10−14; the table in the demo below is recomputed in your browser, whose round-off differs, so the last digits differ too, all below 10−13.

图 12.2Figure 12.2

演示里每个箭头是移动一个节点时 CD 的变化率。只有壁面节点的移动改变物体的形状;内部与远场节点的移动只改变网格,CD 仍会变,因为离散解依赖网格。要得到对物体形状的梯度,还需要一条网格变形链:给物面形状参数 s,先把壁面的位移传给所有节点,X = X(s),再用链式法则 dCD/ds = (dCD/dX)(dX/ds)。本页只算到 dCD/dX,不含网格变形。

Each arrow of the demo is the rate of change of CD as one node moves. Only the moves of the wall nodes change the body's shape; moving an interior or far-field node changes only the mesh, and CD still changes because the discrete solution depends on the mesh. A gradient with respect to the body's shape needs a mesh-deformation chain as well: for shape parameters s of the wall, carry the wall's displacement to every node, X = X(s), and apply the chain rule dCD/ds = (dCD/dX)(dX/ds). This page stops at dCD/dX, with no mesh deformation.

流动参数的导数(演示最后一行)也是第 0 级离散问题的精确导数,但离连续问题的导数可能很远。附录 A 把格点格式加密到第 4 级:dCD/dα = −1.389,连续伴随给出 −1.426。这不是导数算错了(第 13、14 节把它核对到舍入误差),而是第 0 级网格离连续问题太远。

The derivatives with respect to the flow parameters (the demo's last line) are exact derivatives of the level-0 discrete problem too, but may be far from the continuous problem's. Appendix A refines the node scheme to level 4: dCD/dα = −1.389, and the continuous adjoint gives −1.426. The derivative is not wrong (Sections 13 and 14 check it to round-off); the level-0 mesh is simply far from the continuous problem.

逐步推导:dCD/dX 经过哪些几何量

Step by step: which geometric quantities dCD/dX passes through

第一步,几何那一遍的输出。几何那一遍把节点坐标 X 变成七个存储数组 𝒢 = (nf, xf, Δx, xi, Vi, Γij, di):面法向、面点、中心连线、中心、体积、最小二乘权重、壁面距离。残差与目标只通过它们读 X:R = R(U, 𝒢(X)),CD = CD(U, 𝒢(X))。

Step 1, the outputs of the geometric pass. The geometric pass turns the node coordinates X into seven stored arrays 𝒢 = (nf, xf, Δx, xi, Vi, Γij, di): face normals, face points, centre lines, centres, volumes, least-squares weights and wall distances. The residual and the objective read X through them only: R = R(U, 𝒢(X)), CD = CD(U, 𝒢(X)).

第二步,链式法则。固定 U*,每个数组 𝒢k 先收集它自己的伴随权重,再经几何那一遍的 Jacobian 回到 X:

Step 2, the chain rule. With U* held, each array 𝒢k first gathers its own adjoint weight, then goes back to X through the Jacobian of the geometric pass:

dCDdX=∑k=17(∂𝒢k∂X)T𝒢ˉk,𝒢ˉk=∂CD∂𝒢k+(∂R∂𝒢k)Tψ

第三步,两次反向扫描。第一次把残差与目标录在以 𝒢 为输入的磁带上,种子是 CˉD=1 与 Rˉ=ψ,一次得到全部 𝒢ˉk;第二次把几何那一遍录在以 X 为输入的磁带上,分别用每个 𝒢ˉk 作种子,得到它的那一份。七份之和就是第 12 节开头那一次反向扫描的结果(那里两条磁带是连在一起录的)。七份各有多大,见图 12.3。

Step 3, two reverse sweeps. The first tapes the residual and the objective with 𝒢 as the inputs and sweeps back with the seeds CˉD=1 and Rˉ=ψ, which gives every 𝒢ˉk at once; the second tapes the geometric pass with X as the input and sweeps back with each 𝒢ˉk as the seed, which gives that array's share. The seven shares sum to the result of the single reverse sweep at the start of Section 12 (where the two tapes are recorded as one). Figure 12.3 shows how large the seven shares are.

第四步,几个 ∂𝒢/∂X 的例子。格点页的对偶面法向由边中点与相邻单元中心的连线拼成,对偶体积是四边形碎片的鞋带面积之和,二者对坐标都是线性或双线性的;最小二乘权重见第 3 节最小二乘梯度推导的第六步,壁面距离见第 2 节壁面距离推导的第三至第五步。

Step 4, some ∂𝒢/∂X. On the node page a dual-face normal is assembled from the segments between an edge midpoint and the adjacent cell centres, and a dual volume is the sum of the shoelace areas of quadrilateral pieces, both linear or bilinear in the coordinates; the least-squares weights are Step 6 of Section 3's least-squares derivation and the wall distances Steps 3 to 5 of Section 2's wall-distance derivation.

(a) 每个数组贡献的大小 ‖·‖₂(对数)(a) the size ‖·‖₂ of each array's share (log)10−310−210−1100101102面法向 nfface normals nf面点 xfface points xf中心连线 Δxcentre lines Δx中心 xicentres xi体积 Vivolumes Vi最小二乘权重 Γijleast-squares weights Γij壁面距离 diwall distances di合计 dCD/dXtotal dCD/dX(b) 同一拆分,一个坐标:节点 1 的 x(b) the same split for one coordinate: x of node 1面法向 nfface normals nf−2.1736面点 xfface points xf−2.2194中心连线 Δxcentre lines Δx0.1087中心 xicentres xi−0.3999体积 Vivolumes Vi0.0000最小二乘权重 Γijleast-squares weights Γij−3.6304壁面距离 diwall distances di−0.0000合计total−8.3146
图 12.3 · dCD/dX 拆到几何那一遍的七个存储数组 𝒢k 上(上面第三步的做法):每个数组的一份是 (∂𝒢k/∂X)T𝒢ˉk,𝒢ˉk 是它的伴随。(a) 各份在 48 个坐标上的 2-范数:本页最大的是面法向 nf(71.36)与中心 xi(44.69);体积与壁面距离只进入 SA 源项,它们的一份不超过 0.022。(b) 节点 1 的 x(第 13 节差分检验的那个坐标):七份有正有负,和就是伴随给出的 dCD/dx1。Figure 12.3 · dCD/dX split over the seven stored arrays 𝒢k of the geometric pass (Step 3 above): each array's share is (∂𝒢k/∂X)T𝒢ˉk, 𝒢ˉk being its adjoint. (a) The 2-norm of each share over the 48 coordinates: the largest on this page are the face normals nf (71.36) and the centres xi (44.69); the volumes and the wall distances enter the SA source only, and their shares are at most 0.022. (b) x of node 1 (the coordinate of Section 13's difference check): the seven shares have both signs, and their sum is the adjoint's dCD/dx1.

核对:七份之和与第 12 节的 dCD/dX 相差 5.0×10−16(相对最大分量);‖dCD/dX‖ = 87.719(本页代码在构建时计算)。

Check: the seven shares sum to Section 12's dCD/dX to 5.0×10−16 (relative to the largest entry); ‖dCD/dX‖ = 87.719 (computed by this page's code at build time).

逐步推导:流动参数与几何那一遍的伴随语句

Step by step: the adjoint statements of the flow parameters and of the geometric pass

第一步,流动参数进入哪些语句。α 与 M 只进入来流数据 u∞ = M√γ(cos α, sin α);μref 进入每一次 μ(T) = μref·1.4T1.5/(T + 0.4) 与来流的 ν̃∞ = 3μref;目标自己还经 eD(α) 与 q∞ = 0.7M² 读 α 与 M。前向在这些语句上放种子 D˙=1,伴随在它们上面收集:

Step 1, which statements the flow parameters enter. α and M enter only the inflow data u∞ = M√γ(cos α, sin α); μref enters every μ(T) = μref·1.4T1.5/(T + 0.4) and the inflow's ν̃∞ = 3μref; the objective itself reads α and M through eD(α) and q∞ = 0.7M². The tangent puts its seed D˙=1 on these statements, and the adjoint collects on them:

αˉ=CL+Mγ (−sin⁡α, cos⁡α)⋅uˉ∞,Mˉ=−2CDM+γ (cos⁡α, sin⁡α)⋅uˉ∞,μˉref=∂CD∂μref∣U+∑μ(T)μμref μˉ+3 ν~ˉ∞

uˉ∞ 与 ν~ˉ∞ 是 Rˉ=ψ 的反向扫描在来流语句里收集到的来流数据的伴随,Σ 跑遍每一次 μ(T) 的求值;CL、−2CD/M 与 ∂CD/∂μref|U 是第 7 节的显式部分。第二步,按语句的种类拆开 ψTf:每一类语句的那一份用它自己在本页状态上对参数的复数步长求,权重取反向扫描在那里给它的值(面循环与源项取第 4 遍反向之后循环看到的权重,第 4 遍自己的语句取 ψ):

uˉ∞ and ν~ˉ∞ are the adjoints of the inflow data that the reverse sweep with Rˉ=ψ collects in the inflow statements, and the Σ runs over every evaluation of μ(T); CL, −2CD/M and ∂CD/∂μref|U are the explicit parts of Section 7. Step 2, ψTf split by the kind of statement: each kind's share by its own complex step in the parameter at this page's state, weighted by what the reverse sweep gives it there (the face loop and the sources at the weights the loops see after pass 4 reversed, pass 4's own statements at ψ):

参数parameter内部对偶面interior dual faces来流半面inflow half-facesSA 源项SA sources第 4 遍pass 4ψTf∂CD/∂DdCD/dD
α000−7.205−7.205−8.373−15.58
M000496.9496.9−542−45.1
μref409.4−3.6550.198418.6424.5196.5621

α 与 M 只进入读 u∞ 的语句:第 4 遍(被替换的四行是 U − U∞);μref 进入内部对偶面、来流半面、SA 源项、第 4 遍。来流半面的 μ 只在能量行里留下(其余四行被替换)。表中每一行的 ψTf 加上显式部分就是 dCD/dD。

α and M enter only the statements that read u∞: pass 4 (the four replaced rows are U − U∞); μref enters the interior dual faces, the inflow half-faces, the SA sources and pass 4. The inflow half-faces' μ survives only in the energy row (the other four rows are replaced). Each row's ψTf plus the explicit part is dCD/dD.

第三步,几何那一遍倒着执行。上一小节第三步的第一次反向扫描给出七个存储数组的伴随 𝒢ˉk,第二次把它们沿几何那一遍的磁带送回节点坐标;这里把第二次扫描照 mesh.js geometry() 的语句逐句写出,它们是上一小节第四步那些导数的转置:

Step 3, the geometric pass backwards. The first reverse sweep of Step 3 of the previous subsection gives the adjoints 𝒢ˉk of the seven stored arrays, and the second sends them back to the node coordinates along the tape of the geometric pass; here the second sweep is written out statement by statement, following mesh.js geometry(), as the transposes of the derivatives of Step 4 of the previous subsection:

di=∣xi−Xa−ξ (Xb−Xa)∣:xˉi+=nw dˉi,Xˉa–=(1−ξ) nw dˉi,Xˉb–=ξ nw dˉiΓij=𝒩i−1Δxij:Δx‾ij+=𝒩i−1Γˉij,𝒩ˉi–=𝒩i−1ΓˉijΓijT𝒩i=∑jΔxijΔxijT:Δx‾ij+=(𝒩ˉi+𝒩ˉiT)Δxij;Δxij=xj−xi:xˉj+=Δx‾ij,xˉi–=Δx‾ijΔx=xR−xL:xˉR+=Δx‾,xˉL–=Δx‾V=12∑k(xkyk+1−xk+1yk):xˉk+=12(yk+1−yk−1) Vˉ,yˉk+=12(xk−1−xk+1) Vˉ

对偶面法向是从边中点到两侧单元中心的各段 s 的 ±(sy, −sx) 之和,它的伴随把权重分给单元中心与边中点,单元中心再平分给单元顶点;对偶体积是四边形碎片的鞋带面积之和。第三行末的 Δxij 是最小二乘模板里的连线(到邻居节点;格点页的模板里没有壁面点),第四行的 Δx 是一个面两侧中心的连线。壁面距离那一句是第 2 节壁面距离推导第三步的转置:前向里 d 对三点的导数是 nw、−(1 − ξ)nw、−ξnw,反向就把 dˉi 按这三个系数分回去。

A dual-face normal is the sum of ±(sy, −sx) over the segments s from the edge midpoint to the adjacent cell centres, and its adjoint shares the weight between the cell centres and the edge midpoint, each cell centre passing its share on equally to the cell's vertices; a dual volume is the sum of the shoelace areas of quadrilateral pieces. The Δxij at the end of the third line is a least-squares stencil's line (to a neighbouring node; the node page's stencils have no wall point), the Δx of the fourth line a face's centre line. The wall-distance statement is the transpose of Step 3 of Section 2's wall-distance derivation: in forward mode d's derivatives with respect to the three points are nw, −(1 − ξ)nw and −ξnw, and reverse mode hands dˉi back with these three coefficients.

核对:三个参数的 ψTf 按语句拆开后,各格之和与整条磁带给出的 ψT∂R/∂D、与 core.js 的参数列算出的 ψTf 相差 1.4×10−15(相对各格的绝对值之和);把几何那一遍的语句照写成程序倒着执行,得到的 dCD/dX 与第 12 节一条磁带给出的相差 4.4×10−16(相对最大分量)(本页代码在构建时计算)。

Check: the three parameters' ψTf split by statement sum to the whole tape's ψT∂R/∂D and to the ψTf of core.js's parameter columns to 1.4×10−15 (relative to the sum of the entries' sizes); the geometric pass's statements written out and run backwards give Section 12's one-tape dCD/dX to 4.4×10−16 (relative to the largest entry) (computed by this page's code at build time).

前向与伴随的代价:51 对 1

The cost of the tangent and the adjoint: 51 against 1

本页的 51 个设计变量逐个用前向求导:每个设计变量先用磁带的前向扫描得到 f = ∂R/∂D,再解一次 A v = −f。图 12.4 把这 51 次求解首尾相接,横轴是与 A 的乘积次数(每次迭代一次):共 4054 次;伴随只解一次 ATψ = −g,95 次,再加两次反向扫描(ψT∂R/∂D 与 ∂CD/∂D)。两种办法给出的 51 个导数最大相对差 1.3×10−15。

This page's 51 design variables, each differentiated by the tangent: a forward sweep of the tape gives f = ∂R/∂D, then one solve of A v = −f. Figure 12.4 puts these 51 solves end to end, with the products with A on the horizontal axis (one per iteration): 4054 in all, while the adjoint solves ATψ = −g once, in 95, plus two reverse sweeps (ψT∂R/∂D and ∂CD/∂D). The 51 derivatives of the two routes differ by at most 1.3×10−15 (relative).

前向tangent伴随adjointα、M、μref 各一次:82、93、92 次迭代α, M, μref, one each: 82, 93, 92 iterations48 个节点坐标各一次48 node coordinates, one each405495 次迭代,再加两次反向扫描:51 个导数一起得到95 iterations, then two reverse sweeps: all 51 derivatives at once01000200030004000与 A(前向)或 AT(伴随)的乘积次数,每次迭代一次products with A (tangent) or AT (adjoint), one per iteration
图 12.4 · 本页 51 个设计变量(3 个流动参数与 48 个节点坐标)逐个用前向求导,与一次伴随的代价。上排是 51 次前向求解 A v = −f,每一段的长度是那一次达到判据(10−13)所用的迭代次数,每次迭代一次与 A 的乘积,首尾相接共 4054 次;下排是伴随的一次求解 ATψ = −g,95 次,之后两次反向扫描给出全部 51 个导数。两条路线给出的导数最大相对差 1.3×10−15。下面的播放器沿横轴移动:前向每走完一段得到一个导数,伴随在第 95 次乘积后一次得到全部。Figure 12.4 · The cost of differentiating this page's 51 design variables (3 flow parameters and 48 node coordinates) one by one with the tangent, against one adjoint. The top row is the 51 tangent solves A v = −f end to end, each segment as long as the iterations that solve took to meet the criterion (10−13), one product with A per iteration: 4054 in all. The bottom row is the adjoint's single solve ATψ = −g, 95 iterations, after which two reverse sweeps give all 51 derivatives. The two routes' derivatives differ by at most 1.3×10−15 (relative). The player below moves along the axis: the tangent gains one derivative per segment, the adjoint all of them after product 95.
第 13 节Section 13

验证:与有限差分对照

Verification against finite differences

中心差分 [CD(D + ε) − CD(D − ε)]/(2ε) 每个设计变量要重算两次流场,每次都从 U* 出发、收敛到舍入底。步长 ε 太大,截断误差 ∝ ε²;ε 太小,重算解残留的舍入误差被 1/ε 放大。二阶格式的步长扫描(与伴随的相对差;α 一列按第 10 节的归一,另一列除以导数本身):

The central difference [CD(D + ε) − CD(D − ε)]/(2ε) re-solves the flow twice per design variable, each time from U* down to the round-off floor. With the step ε too large the truncation error ∝ ε² dominates; with ε too small the round-off left in the re-solved flows is amplified by 1/ε. The step sweep for the second-order scheme (relative difference from the adjoint; for α one column in the normalisation of Section 10 and one over the derivative itself):

εα(按两部分归一)α (over the parts)α(除以导数本身)α (over the derivative)节点 1 的 xx of node 1
10−28.3×10−58.3×10−56.7×10−5
10−38.3×10−78.3×10−76.7×10−7
10−48.3×10−98.3×10−96.7×10−9
10−52.2×10−112.2×10−111.4×10−10
10−61.3×10−91.3×10−91.2×10−9
10−79.0×10−99.0×10−91.7×10−8
10−89.0×10−99.0×10−97.6×10−8

截断误差按 ε² 下降,α 在 ε = 10−5、节点 1 的 x 在 ε = 10−5 处与舍入误差相遇:最好的差分与伴随的相对差,α 为 2.2×10−11(除以导数本身 2.2×10−11),节点 1 的 x 为 1.4×10−10。最低点的具体数值取决于重算解的舍入误差,换一台机器、换一个浏览器都会略有不同(下面的演示在本机重算)。差分只能验证到这个量级;更严格的核对由复数步长(第 14 节)给出。

The truncation error falls as ε² and meets the round-off at ε = 10−5 for α and ε = 10−5 for x of node 1: the best difference agrees with the adjoint to a relative 2.2×10−11 for α (2.2×10−11 over the derivative itself) and 1.4×10−10 for x of node 1. The exact value at the minimum depends on the round-off of the re-solved flows and varies a little from machine to machine and browser to browser (the demo below re-solves here). A difference can verify no further than this; the complex step (Section 14) gives the stricter check.

图 13.1Figure 13.1
第 14 节Section 14

复数步长

The complex step

怎样实现

How to implement it

同一份核代码换上复数算术:加减乘直接算,除法用 Smith 算法(不会溢出,虚部很小时实部与实数除法逐位相同),sqrt、exp、实数次幂取主值;|x|、min、max 与所有分支(S̃ 的两支、r 的截断、壁面距离的最近边与垂足位置、Roe 的 |Λk|)都只看实部。步长 ε = 10−30 时虚部比实部小约 30 个数量级,两个虚部的乘积小约 60 个数量级,永远碰不到实部的最后一位:每个实部都与实数代码逐位相同。

The same kernel code on complex arithmetic: addition, subtraction and multiplication as they are; division by Smith's algorithm (it never overflows, and with tiny imaginary parts its real part is bit for bit the real division); sqrt, exp and real powers on their principal branches; |x|, min, max and every branch (the two branches of S̃, the cap on r, the nearest wall edge and the foot position, Roe's |Λk|) read the real part only. With the step ε = 10−30 the imaginary parts stay about 30 orders of magnitude below the real ones and a product of two imaginary parts about 60, which never reaches the last bit of a real part: every real part is bit for bit the real code's.

从收敛的流场出发

Starting from the converged flow

把设计变量换成 D + iε,从 U* + 0i 出发,用同一个 K 迭代 U ← U − K R(U)。实部停在 U*;虚部的方程是

Replace the design variable by D + iε, start from U* + 0i, and iterate U ← U − K R(U) with the same K. The real part stays at U*; the imaginary part obeys

Im⁡Uk+1ε=Im⁡Ukε−K(A Im⁡Ukε+f)

这正是前向迭代:Im Uk/ε 就是 vk。二阶格式前 40 次迭代上,Im CD/ε 与前向估计的最大相对差 3.4×10−15(按第 10 节的归一;除以导数本身 3.4×10−15)。收敛后复数步长与伴随的相对差:3 个流动参数 9.2×10−16(按第 10 节的归一;除以导数本身 9.2×10−16),48 个坐标(按范数:最大差除以最大导数)1.3×10−15。

This is exactly the tangent iteration: Im Uk/ε is vk. Over the first 40 iterations of the second-order scheme, Im CD/ε and the tangent estimate differ by at most 3.4×10−15 (in the normalisation of Section 10; 3.4×10−15 over the derivative itself). Once converged, the complex step agrees with the adjoint to a relative 9.2×10−16 for the 3 flow parameters (in the normalisation of Section 10; 9.2×10−16 over the derivatives themselves), and to 1.3×10−15 for the 48 coordinates (normwise: the largest difference over the largest derivative).

图 14.1Figure 14.1
第 15 节Section 15

精度阶:制造解检验

Order of accuracy: manufactured solutions

伴随给出的是离散格式的精确导数,与格式本身几阶精度无关;格式的精度阶决定的是离散解,以及由它算出的 CD 与导数,离连续问题有多远。附录 A 的制造解只检验连续伴随的 P1 求解器;这一节检验本页的有限体积格式本身,一字不改:Roe 通量、无权最小二乘重构、SU2 式修正平均梯度的粘性通量、TMR 守恒形式的 SA(含 ft2、2012 年修正的 S̃、r ≤ 10 的截断与密度梯度项)、Sutherland 粘度,格心与格点、一阶与二阶。做法是:先选光滑的函数当精确解,由它反推出源项,再在一族逐级一致加密的网格上求解,看误差随网格尺寸按几次方减小。

The adjoint gives the exact derivative of the discrete scheme, whatever the scheme's order of accuracy; the order decides how far the discrete solution, and the CD and derivatives computed from it, are from the continuous problem. The manufactured solution of Appendix A tests only the continuous adjoint's P1 solver; this section tests the page's finite-volume scheme itself, exactly as implemented: the Roe flux, unweighted least-squares reconstruction, SU2's corrected average gradient for the viscous flux, SA in TMR's conservative form (ft2, the 2012 modified S̃, the cap r ≤ 10 and the density-gradient term included), Sutherland's viscosity; cell and node, first and second order. The method: choose smooth functions as the exact solution, derive the source that makes them one, solve on a family of uniformly refined meshes, and see by what power of the mesh size the error falls.

两个构造解

Two manufactured solutions

两个解的 ρ、u、v、T 相同,ν̃ 不同:

The two solutions share ρ, u, v and T, and differ in ν̃:

ρe=2sin⁡(9x10+310)cos⁡(7y10−15)25+1,Te=3cos⁡(x2+3y5+15)50+1
ue=−3y50+sin⁡(7x10+y2+310)50+625,ve=3x50+cos⁡(3x5−4y5+110)50+3100
ν~e R=3sin⁡(4x5−2y5+12)1000+1100,ν~e M=21sin⁡(4x5−2y5+12)1000+750

μref 取本页的 0.02。它们的涡量 ∂ve/∂x − ∂ue/∂y 在 [0.098, 0.129] 之间,处处同号,所以 Ω = |ω| 是光滑的。两个解各把 SA 的分支固定在整个区域:

μref is the page's 0.02. Their vorticity ∂ve/∂x − ∂ue/∂y lies in [0.098, 0.129], one sign everywhere, so Ω = |ω| is smooth. Each solution keeps the SA branches fixed over the whole domain:

  • R(常规分支):χ 在 [0.33, 0.69],fv2 > 0,所以 B > 0,S̃ = Ω + B 处处是第一支,r ≤ 1/fv2 处处小于 10,不截断。ft2 很大(在 [0.94, 1.14]),μt/μ 很小(最大 6.5×10−4):这个解检验 fv2、ft2 与完整的 fw(r)。R (the regular branch): χ in [0.33, 0.69], fv2 > 0, so B > 0 and S̃ = Ω + B is the first branch everywhere, and r ≤ 1/fv2 stays below 10: never capped. ft2 is large (in [0.94, 1.14]) and μt/μ small (at most 6.5×10−4): this solution tests fv2, ft2 and the whole fw(r).
  • M(修正分支):χ 在 [5.40, 8.60],fv2 < 0,B < −c2Ω 处处成立,S̃ 处处取 2012 年的修正分支,r 处处截断在 10。μt/μ 在 [1.65, 5.50]:涡粘性主导平均流,这个解检验 μt 对动量与能量方程的耦合。M (the modified branch): χ in [5.40, 8.60], fv2 < 0, and B < −c2Ω holds everywhere, so S̃ takes the 2012 modified branch everywhere and r is capped at 10 everywhere. μt/μ lies in [1.65, 5.50]: the eddy viscosity drives the mean flow, and this solution tests the coupling of μt into the momentum and energy equations.

余量在两处量:一处是各级网格上所有求源项的中心(第 1–5 级,两种格式),一处是整个区域里的 144720 个点(从物体中心出发的 720 条射线,每条从壁面到远场 201 个点,最近的离壁面只有间隙的万分之一)。都是正数,分支在整个区域里都没有切换:

The margins are measured in two ways: at every centre where the source is evaluated on every level (levels 1–5, both schemes), and at 144720 points over the whole domain (720 rays from the body's centre, 201 points each from the wall to the far field, the first a ten-thousandth of the gap from the wall). All are positive: no branch switches anywhere in the domain:

余量marginRM
S̃ 的分支:±(B + c2Ω)/Ω(区域 / 中心)the S̃ branch: ±(B + c2Ω)/Ω (domain / centres)0.790 / 0.7921.312 / 1.349
r 的截断:±(r0 − 10)/10(区域 / 中心)the cap on r: ±(r0 − 10)/10 (domain / centres)0.710 / 0.7100.823 / 0.864
涡量:min|ω| / max|ω|,同号vorticity: min|ω| / max|ω|, one sign0.759 ✓0.759 ✓
ρ / T 的范围the ranges of ρ / T0.922–1.080 / 0.994–1.0600.922–1.080 / 0.994–1.060

Roe 通量里的 |q̃| 是唯一避不开的不可导点:面的朝向遍布各个方向,总有面几乎与流速平行。|q̃| 只出现在耗散项里,乘的是两侧状态的跳跃(二阶 O(h²)、一阶 O(h)),它是 Lipschitz 连续的,不影响精度,只影响可导性,而这一节不求导。

Roe's |q̃| is the one kink that cannot be avoided: the faces point in every direction, and some face is always nearly parallel to the flow. |q̃| appears only in the dissipation, multiplying the jump between the two states (O(h²) at second order, O(h) at first), and it is Lipschitz: it affects differentiability, not accuracy, and this section takes no derivatives.

源项与边界

The source and the boundaries

把精确解代入第 1 节的方程,对连续通量求散度,再减去 SA 源项:

Put the exact solution into the equations of Section 1, take the divergence of the continuous fluxes, and subtract the SA source:

s(x)=∇⋅(𝐅c(We)−𝐅v(We,∇We))−S(We,∇We,d),Ri(U)  ←  Ri(U)−Vi s(xi)

s 由 sympy 对解析的通量逐项求导得到(mms_gen.py),从不调用离散残差。壁面距离 d 只以代数方式进入 S,所以 s 在每个控制体中心用格式自己的 di 求值;积分用格式自己的单点规则(与 SA 源项相同),xi 是节点。sympy 的源项与本页代码的通量公式互相核对过:在任取的点上用四阶中心差分对 model.js 的通量求散度,两者在差分截断与舍入误差内一致(check_mms.js)。为了只检验内部离散,这一节把精确解加在所有边界上(core.js 的 mms 模式;本页其余各节的边界条件不变):所有边界节点的五行都替换成 U − Ue,边界半面不再调用;内部节点的最小二乘模板照常包括边界节点。

s comes from sympy differentiating the analytic fluxes term by term (mms_gen.py), never from the discrete residual. The wall distance d enters S algebraically only, so s is evaluated at every control volume's centre with the scheme's own di; the integral takes the scheme's own one-point rule (the SA source's), xi being the node. The sympy source and this page's flux formulas were checked against each other: at arbitrary points, the divergence of model.js's fluxes by fourth-order central differences agrees with the sympy source within the differences' truncation and round-off (check_mms.js). To test the interior discretisation alone, this section imposes the exact solution on every boundary (core.js's mms mode; the boundary conditions of the rest of the page are untouched): the five rows of every boundary node are replaced by U − Ue and the boundary half-faces are not called; the interior nodes' least-squares stencils include the boundary nodes as usual.

网格族与误差

The mesh family and the error

第 1–5 级网格由第 0 级逐级一致细分得到(每个三角形由三条边的中点分成 4 个,每个四边形由四条边的中点与顶点平均点分成 4 个),物面与远场都是直边八边形,每一级的计算域完全相同,网格尺寸逐级减半。误差与各自的未知量比较:格心格式的 Ui 是单元平均,与精确解守恒量的单元平均比较(每个三角形 36 点 Gauss 积分,四边形分成两个三角形);格点格式的 Ui 是节点值,与精确的节点值比较。用体积加权的 L2 范数;网格尺寸逐级减半,所以观测阶 p 就是相邻两级误差之比以 2 为底的对数。每一级都解到第 6 节的判据(先用本页的伪时间迭代 40 步,没到判据再用 Newton–GMRES 收尾),迭代误差远小于离散误差。

Levels 1–5 come from level 0 by uniform subdivision (a triangle into 4 through its edge midpoints, a quadrilateral into 4 through its edge midpoints and vertex average); the body and the far field are straight-sided octagons, so every level covers exactly the same domain and the mesh size halves from level to level. The error is measured against each scheme's own unknowns: the cell scheme's Ui is a cell average, compared with the cell average of the exact conserved variables (a 36-point Gauss rule per triangle, a quadrilateral split into two); the node scheme's Ui is a nodal value, compared with the exact nodal value. The norm is the volume-weighted L2 norm; the mesh size halves from level to level, so the observed order p is the base-2 logarithm of the ratio of the errors on neighbouring levels. Every level is solved to the criterion of Section 6 (40 steps of this page's pseudo-time iteration, then Newton–GMRES where the criterion is not met yet), so the iteration error is far below the discretisation error.

解solution格式schemep(ρ)p(ρu)p(ρv)p(ρE)p(ρν̃)p(CD)
R格心一阶cell first order0.710.940.950.700.840.80
R格心二阶cell second order1.731.932.011.861.92(0.51)
R格点一阶node first order0.860.870.890.820.841.02
R格点二阶node second order2.002.062.121.962.041.99
M格心一阶cell first order0.760.940.900.760.770.78
M格心二阶cell second order1.991.911.951.941.981.86
M格点一阶node first order0.690.890.910.690.700.72
M格点二阶node second order2.032.042.122.012.062.03

表中是第 4→5 级的观测阶(五个守恒分量的 L2 误差,以及目标 CD:壁面节点动量行的反作用,对精确的 eD·∮(ρu(u·n) + pn − τn)ds/q∞),各级的误差在下面的图与展开表里。CD 一栏括号里的值紧接在误差的一次变号之后,不代表收敛速率。

The table gives the observed orders from level 4 to 5 (the L2 errors of the five conserved components, and of the objective CD: the reaction of the wall nodes' momentum rows, against the exact eD·∮(ρu(u·n) + pn − τn)ds/q∞); the errors on every level are in the figure and the expandable table below. A value in brackets in the CD column comes right after a sign change of the error and does not measure a convergence rate.

1e-71e-61e-51e-41e-31e-22⁻¹2⁻²2⁻³2⁻⁴2⁻⁵网格尺寸 h/h₀(每级减半)mesh size h/h₀ (halving per level)解 R(常规分支)solution R (regular branch)hh²1e-71e-61e-51e-41e-31e-22⁻¹2⁻²2⁻³2⁻⁴2⁻⁵网格尺寸 h/h₀(每级减半)mesh size h/h₀ (halving per level)解 M(修正分支,r 截断)solution M (modified branch, r capped)hh²格心cell格点node二阶(实线)second order (solid)一阶(虚线)first order (dashed)‖e(ρ)‖‖e(ρν̃)‖点线:斜率 1(h)与 2(h²)的参考线dotted: reference slopes 1 (h) and 2 (h²)
图 15.1 · 两个构造解上密度与 ρν̃ 的 L2 误差随网格加密(双对数坐标,横轴向右网格变细)。实线二阶、虚线一阶;蓝色格心、红色格点。点线是每级减半(斜率 1)与减为 1/4(斜率 2)的参考。五个分量各自的观测阶见上表。Figure 15.1 · The L2 errors of the density and of ρν̃ on the two manufactured solutions under refinement (log-log; finer meshes to the right). Solid second order, dashed first order; blue cell, red node. The dotted lines are reference slopes halving (1) and quartering (2) per level. The observed order of each of the five components is in the table above.
展开:各级网格的 L2 误差(解 R)Expand: the L2 errors on every level (solution R)
格式scheme级levelN‖e(ρ)‖‖e(ρu)‖‖e(ρv)‖‖e(ρE)‖‖e(ρν̃)‖|CD − CD,e|
格心一阶cell first order1962.9×10−37.3×10−35.3×10−37.3×10−31.2×10−43.8×10−2
格心一阶cell first order23841.7×10−33.7×10−32.5×10−34.4×10−36.7×10−54.7×10−2
格心一阶cell first order315361.0×10−31.9×10−31.2×10−32.7×10−34.0×10−53.2×10−2
格心一阶cell first order461446.3×10−49.9×10−46.1×10−41.7×10−32.3×10−51.9×10−2
格心一阶cell first order5245763.8×10−45.2×10−43.2×10−41.0×10−31.3×10−51.1×10−2
格心二阶cell second order1965.4×10−48.4×10−47.1×10−41.6×10−32.2×10−55.8×10−3
格心二阶cell second order23841.3×10−42.0×10−41.7×10−43.7×10−47.2×10−61.4×10−3
格心二阶cell second order315363.9×10−55.2×10−53.7×10−58.9×10−52.3×10−61.6×10−4
格心二阶cell second order461441.2×10−51.4×10−58.6×10−62.3×10−56.5×10−74.3×10−5
格心二阶cell second order5245763.8×10−63.6×10−62.1×10−66.4×10−61.7×10−73.0×10−5
格点一阶node first order1805.0×10−38.9×10−39.4×10−31.3×10−22.0×10−43.2×10−1
格点一阶node first order22882.8×10−35.7×10−35.8×10−37.2×10−31.6×10−41.3×10−1
格点一阶node first order310881.6×10−33.4×10−33.4×10−34.0×10−31.1×10−45.5×10−2
格点一阶node first order442248.5×10−42.0×10−31.9×10−32.3×10−36.4×10−52.5×10−2
格点一阶node first order5166404.7×10−41.1×10−31.0×10−31.3×10−33.6×10−51.3×10−2
格点二阶node second order1801.7×10−32.6×10−31.7×10−32.9×10−35.3×10−51.9×10−1
格点二阶node second order22884.8×10−46.8×10−44.1×10−41.0×10−31.4×10−55.5×10−2
格点二阶node second order310881.3×10−41.7×10−49.9×10−52.9×10−43.6×10−61.5×10−2
格点二阶node second order442243.2×10−54.0×10−52.3×10−57.9×10−58.5×10−73.8×10−3
格点二阶node second order5166407.9×10−69.5×10−65.3×10−62.0×10−52.1×10−79.6×10−4
展开:各级网格的 L2 误差(解 M)Expand: the L2 errors on every level (solution M)
格式scheme级levelN‖e(ρ)‖‖e(ρu)‖‖e(ρv)‖‖e(ρE)‖‖e(ρν̃)‖|CD − CD,e|
格心一阶cell first order1964.2×10−35.7×10−33.4×10−31.1×10−24.8×10−43.0×10−1
格心一阶cell first order23843.0×10−32.8×10−31.6×10−37.8×10−33.5×10−42.3×10−1
格心一阶cell first order315361.9×10−31.4×10−38.2×10−45.0×10−32.2×10−41.5×10−1
格心一阶cell first order461441.2×10−37.5×10−44.4×10−43.0×10−31.4×10−49.4×10−2
格心一阶cell first order5245766.9×10−43.9×10−42.4×10−41.8×10−38.0×10−55.5×10−2
格心二阶cell second order1967.2×10−45.9×10−44.9×10−41.8×10−31.8×10−43.6×10−2
格心二阶cell second order23842.4×10−41.5×10−41.2×10−45.1×10−44.9×10−51.4×10−2
格心二阶cell second order315367.2×10−53.9×10−52.6×10−51.5×10−41.3×10−54.7×10−3
格心二阶cell second order461442.0×10−51.0×10−56.2×10−64.1×10−53.4×10−61.4×10−3
格心二阶cell second order5245765.0×10−62.8×10−61.6×10−61.1×10−58.6×10−73.8×10−4
格点一阶node first order1805.6×10−36.7×10−36.5×10−31.5×10−26.5×10−44.5×10−1
格点一阶node first order22883.5×10−34.0×10−33.7×10−39.4×10−34.2×10−42.6×10−1
格点一阶node first order310882.1×10−32.3×10−32.1×10−35.8×10−32.7×10−41.6×10−1
格点一阶node first order442241.3×10−31.3×10−31.1×10−33.6×10−31.6×10−49.9×10−2
格点一阶node first order5166408.3×10−46.8×10−46.0×10−42.2×10−31.0×10−46.0×10−2
格点二阶node second order1801.9×10−31.6×10−31.1×10−34.1×10−31.8×10−42.8×10−1
格点二阶node second order22886.0×10−44.1×10−42.5×10−41.4×10−36.1×10−58.4×10−2
格点二阶node second order310881.7×10−41.0×10−45.7×10−54.2×10−41.7×10−52.3×10−2
格点二阶node second order442244.3×10−52.4×10−51.3×10−51.1×10−44.4×10−65.9×10−3
格点二阶node second order5166401.1×10−55.9×10−63.0×10−62.7×10−51.1×10−61.4×10−3

结果

What the numbers say

  • 二阶格式:五个分量的观测阶在 1.73–2.12 之间;低于 1.8 的只有解 R 上格心格式的 ρ(逐级 2.07、1.71、1.65、1.73),其余在 1.86–2.12 之间,都在 2 附近。质量方程只有对流、没有扩散;下一条说明,纯对流问题在三角形网格上的收敛阶可以低于格式的形式精度。Second order: the observed orders of the five components lie between 1.73 and 2.12; the only ones below 1.8 are the cell scheme's ρ on solution R (2.07, 1.71, 1.65, 1.73 level by level), and the rest lie between 1.86 and 2.12, all near 2. The mass equation has convection and no diffusion; the next item shows that on triangular meshes a purely convective problem can converge more slowly than the scheme's formal order.
  • 一阶格式:动量分量的观测阶在 0.87–0.95 之间;密度、能量与 ρν̃ 在 0.69–0.86 之间,都明显低于 1。与前一段相比,后三者的阶变化了 −0.02 到 +0.12,有升有降,这些网格还定不下它们的渐近阶。质量方程只有对流、没有扩散;ρu、ρv、ρE、ρν̃ 的误差分别含有 u e(ρ)、v e(ρ)、E e(ρ)、ν̃ e(ρ) 一项(例如 e(ρu) ≈ u e(ρ) + ρ e(u)),除非两项相消,它们最终不会比 e(ρ) 收敛得快。纯对流问题上,迎风型格式在三角形网格上的收敛阶可以低于形式精度:Peterson(1991)构造了一族三角形网格,一阶迎风格式(零次间断 Galerkin)在其上对纯对流问题只有 h1/2。本页一阶格式的观测阶都在 1/2 与 1 之间。First order: the momentum components converge at orders between 0.87 and 0.95; the density, the energy and ρν̃ between 0.69 and 0.86, all clearly below 1. From the previous pair of levels the orders of these three changed by between −0.02 and +0.12, some rising and some falling, so these meshes do not settle their asymptotic orders. The mass equation has convection and no diffusion; the errors of ρu, ρv, ρE and ρν̃ contain the terms u e(ρ), v e(ρ), E e(ρ) and ν̃ e(ρ) (for example e(ρu) ≈ u e(ρ) + ρ e(u)), so unless the two terms cancel they cannot in the end converge faster than e(ρ). On purely convective problems an upwind-type scheme can converge on triangular meshes more slowly than its formal order: Peterson (1991) constructed a family of triangular meshes on which the first-order upwind scheme (discontinuous Galerkin of degree zero) converges only as h1/2 on a purely convective problem. At first order every observed order here lies between 1/2 and 1.
  • 目标函数 CD(二阶格式):解 R 上格心格式的误差逐级为 −5.8×10−3、−1.4×10−3、−1.6×10−4、4.3×10−5、3.0×10−5,在第 3、4 级之间变号。变号说明误差里至少有两部分符号相反、随 h 减小的快慢不同;变号的那一段没有阶,紧接着的一段里两部分仍在相消,观测阶也不代表收敛速率。最后两级的观测阶(不计受变号影响的)在 1.86–2.03 之间。格点格式的反作用力来自离散动量守恒本身,测得的阶为 1.99(解 R)与 2.03(解 M)。The objective CD (second order): the cell scheme's error on solution R is −5.8×10−3, −1.4×10−3, −1.6×10−4, 4.3×10−5, 3.0×10−5 level by level, changing sign between levels 3 and 4. A sign change means that the error has at least two parts of opposite sign that shrink at different rates with h; the pair of levels across the sign change has no order, and in the pair right after it the two parts still cancel, so its observed order does not measure a convergence rate either. The observed orders between the last two levels (leaving out those affected by a sign change) lie between 1.86 and 2.03. The node scheme's reaction force comes from the discrete momentum balance itself, with measured orders 1.99 (solution R) and 2.03 (solution M).
  • 对伴随的意义:第 8–14 节核对的是伴随给出离散 CD 的精确导数,与格式几阶无关;这一节测的是这个离散问题以多快的速度趋于连续问题。两者都是离散导数趋于连续问题导数的前提;这个收敛本身在附录 A 里直接比较。What this means for the adjoint: Sections 8–14 check that the adjoint gives the exact derivative of the discrete CD, whatever the scheme's order; this section measures how fast the discrete problem approaches the continuous one. Both are prerequisites for the discrete derivatives to approach the continuous problem's; that convergence itself is compared directly in Appendix A.

范围:这里检验的是光滑解在固定多边形区域上的内部离散。真实算例的来流与出口交界点、物面角点与不可分辨的来流薄层(附录 A.6、B.6)不在检验范围内;它们可能让真实算例收敛得比这里慢。

Scope: what is tested here is the interior discretisation on a smooth solution over a fixed polygonal domain. The junctions of inflow and outlet, the corners of the body and the unresolved inflow sublayer of the real case (Appendices A.6 and B.6) are outside the test; they can make the real case converge more slowly than the orders found here.

第 16 节Section 16

伴随方程的三种解法:GS、GMRES 与 LU

Three solvers for the adjoint equation: GS, GMRES and LU

第 11 节用不动点迭代 ψk+1 = ψk − KT(ATψk + g) 解伴随方程。它每步便宜(一次 AT 乘积、两次对称扫描),但收敛速率由 ρ(I − KA) 决定:本页二阶格式 ρ(I − KA) = 0.712,要 95 步才满足判据。这一节在同一个系统 ATψ = −g(120 个未知量)上比较三种解法;它们解的是同一个方程,所以给出同一个 ψ、同一组导数,差别只在怎样到达那里。

Section 11 solves the adjoint equation by the fixed point ψk+1 = ψk − KT(ATψk + g). Each step is cheap (one product with AT, two symmetric sweeps), but the rate is set by ρ(I − KA): for this page's second-order scheme ρ(I − KA) = 0.712, and the criterion takes 95 steps. This section compares three solvers on the same system ATψ = −g (120 unknowns); they solve the same equation, so they give the same ψ and the same derivatives, and differ only in how they get there.

  • GS 不动点(第 11 节):沿 KT 给出的方向一步一步修正。只要 ρ(I − KA) < 1 就收敛,误差每步乘约 ρ(I − KA)。The GS fixed point (Section 11): corrections along the directions KT gives, one at a time. It converges whenever ρ(I − KA) < 1, the error shrinking by about ρ(I − KA) per step.
  • GMRES,以同一个 KT 作右预处理:保存已经产生的方向 KTv0, KTv1, …,在它们张成的空间里取使残差 ‖ATψ + g‖ 最小的组合(Arnoldi 正交化加一个小最小二乘问题)。每步也是一次 AT 乘积、一次 KT,外加正交化;不需要 ρ(I − KA) < 1(不重启时,AT 与 KT 都非奇异就在 n 步内收敛)。本页每 30 步重启一次,限制存储。GMRES, right-preconditioned by the same KT: it keeps the directions produced so far, KTv0, KTv1, …, and takes the combination in their span that minimises the residual ‖ATψ + g‖ (Arnoldi orthogonalisation plus a small least-squares problem). Each step is again one product with AT and one KT, plus the orthogonalisation; it does not need ρ(I − KA) < 1 (without restarts it converges within n steps whenever AT and KT are nonsingular). This page restarts every 30 steps to bound the storage.
  • 直接 LU 分解:把 AT 显式装配出来(用 120 次 residual_d 取出 A 的各列,再转置),做带部分主元的 Gauss 消元 ΠAT = LU,再做两次三角回代。没有迭代,精度只受舍入误差限制;代价是 n² = 14400 个数的存储与约 n³/3 次乘法,而且它不是 matrix-free 的。对这张 24 个控制体的网格毫无问题;每加密一级 n 约乘 4,存储约乘 16,工作量约乘 64,在实际网格上不可行。A direct LU factorisation: assemble AT explicitly (the columns of A from 120 calls of residual_d, then transposed), eliminate with partial pivoting, ΠAT = LU, and solve two triangular systems. No iteration, accuracy limited by round-off only; the price is storing n² = 14400 numbers, about n³/3 multiplications, and giving up the matrix-free form. On this mesh of 24 control volumes that is no problem at all; each level of refinement multiplies n by about 4, the storage by about 16 and the work by about 64, which rules it out on practical meshes.

构建页面时测得的结果(与 GS 不动点的导数比较;按第 10 节的归一,括号里是除以导数本身):

Measured when the page was built (derivatives compared with the GS fixed point's; in the normalisation of Section 10, over the derivatives themselves in brackets):

二阶格式second orderGSGMRESLU
迭代步数(AT 乘积)iterations (products with AT)9540 (43)— (120)
最终残差 ‖ATψ + g‖(均方根)final residual ‖ATψ + g‖ (rms)6.7×10−156.6×10−142.0×10−14
导数与 GS 的最大相对差largest relative difference of the derivatives from GS—5.5×10−15 (5.2×10−14)4.7×10−15 (2.6×10−14)
一阶格式:迭代步数first order: iterations3917—

三种解法给出的导数在舍入误差内相同。GMRES 的步数更少(40 对 95),因为它不只沿最新的方向走,而是在所有已产生的方向里挑最好的组合:GS 迭代里衰减得慢、接近 ρ(I − KA) 的那几个误差分量,GMRES 几步就能把它们一起消掉。它的代价是每步的正交化与 30 个基向量的存储。LU 的装配本身就要 120 次 residual_d,比 GMRES 的 43 次乘积多,外加 O(n³) 的分解;它的用处是给迭代解法一个不依赖迭代的参照。

The three solvers give the same derivatives to round-off. GMRES needs fewer steps (40 against 95): it does not just follow the latest direction but picks the best combination of all directions produced so far, and the few error components that the GS iteration damps slowly, near ρ(I − KA), it removes together within a few steps. Its price is the orthogonalisation per step and the storage of 30 basis vectors. LU's assembly alone takes 120 calls of residual_d, more than GMRES's 43 products, plus the O(n³) factorisation; its use is a reference for the iterative solvers that involves no iteration at all.

图 16.1Figure 16.1

上面演示里的播放器把 GS 与 GMRES 的残差逐次画出来(LU 没有迭代,只在最后标出它的残差):两条线在同一个判据处停下,给出同一个 ψ。

The player of the demo above draws the GS and GMRES residuals iteration by iteration (LU has no iterations and is marked with its residual at the end): both lines stop at the same criterion and give the same ψ.

第 17 节Section 17

总结

Summary

做什么what怎样做how
residual(U)R(U)R(U)几遍循环:π、Γ、面、源项、强边界行passes: π, Γ, faces, source, strong rows
residual_d(U, U_d)R˙=AU˙R˙=AU˙同样的几遍、同样的顺序,核换成局部 Jacobianthe same passes in the same order, kernels replaced by local Jacobians
residual_b(U, R_b)Uˉ=ATRˉUˉ=ATRˉ几遍倒序,每遍转置;强边界行(壁面与来流)最先处理the passes reversed, each transposed; the strong rows (wall and inflow) first
solveR(U) = 0R(U) = 0伪时间 + 两次对称块 GS(P = 一阶 Roe + 薄剪切层)pseudo-time + two symmetric block GS sweeps (P = first-order Roe + thin shear layer)
tangentA v = −fA v = −f同一个 K,每个设计变量一次the same K, once per design variable
adjointATψ = −gATψ = −gKT = PT 上的同一个 SGS,一次得到全部导数KT = the same SGS on PT, all derivatives at once
complex stepIm C_D / εIm C_D / ε从 U* 出发、同一个 K,虚部就是前向迭代from U*, the same K: the imaginary part is the tangent iteration
FD[C_D(D+ε) − C_D(D−ε)]/2ε[C_D(D+ε) − C_D(D−ε)]/2ε每个变量两次重算,精度受步长限制two re-solves per variable, accuracy limited by the step
MMS‖U − U_e‖ ∝ h^p‖U − U_e‖ ∝ h^p第 15 节:两个制造解、第 1–5 级网格;本页格式二阶 p = 1.96–2.12,一阶 0.69–0.91Section 15: two manufactured solutions, levels 1–5; this page's scheme p = 1.96–2.12 at second order, 0.69–0.91 at first
GMRES, LUATψ = −gATψ = −g第 16 节:同一个方程、同一组导数;GMRES 40 步,GS 95 步Section 16: the same equation, the same derivatives; GMRES in 40 steps, GS in 95
continuousλ = (λ_ρ, β, ζ, φ)λ = (λ_ρ, β, ζ, φ)附录 A:连续伴随方程与边界条件,P1 有限元求解;加密时导数与 ψ 给出的相互靠近Appendix A: the continuous adjoint equations and boundary conditions, solved by P1 finite elements; under refinement its derivatives approach ψ's
  • 离散伴随只需要两样东西:每个局部核的转置(局部磁带反向扫描)和各遍的倒序。多遍结构(原始变量、梯度、面、源项)完全保留。The discrete adjoint needs only two things: the transpose of each local kernel (a reverse sweep of its local tape) and the passes in reverse order. The pass structure (primitives, gradients, faces, source) is kept entirely.
  • 最小二乘让 A 的一行伸到邻居的邻居;伴随里对应的是梯度的权重回到整个模板。近似 Jacobian 只要一阶连接,Gauss–Seidel 与它的转置都只用 P。The least squares makes a row of A reach the neighbours' neighbours; in the adjoint this is a gradient's weight returning to its whole stencil. The approximate Jacobian needs first-order coupling only, and Gauss–Seidel and its transpose use P alone.
  • 对称 Gauss–Seidel 的转置就是在 PT 上的同一个算法:前向与伴随在每一步给出同一个导数估计,三个迭代共用一个收敛速率。The transpose of symmetric Gauss–Seidel is the same algorithm on PT: the tangent and the adjoint give the same derivative estimate at every iteration, and the three iterations share one rate.
  • 导数在当前解所在的分支上取;本页的解离所有分支点都足够远(第 4 节)。复数步长与伴随的相对差:流动参数 9.2×10−16(按第 10 节的归一;除以导数本身 9.2×10−16),48 个坐标(按范数)1.3×10−15。Derivatives are taken on the branch the solution sits on; this page's solution is far enough from every switch (Section 4). The complex step and the adjoint differ by a relative 9.2×10−16 for the flow parameters (in the normalisation of Section 10; 9.2×10−16 over the derivatives themselves), and by 1.3×10−15 (normwise) for the 48 coordinates.
  • 伴随的精确性与格式的精度是两件事:第 15 节用制造解测得本页格式的阶,第 16 节说明换一种线性解法(GMRES、LU)只改变到达同一个 ψ 的路径。The exactness of the adjoint and the accuracy of the scheme are two things: Section 15 measures this page's order with manufactured solutions, and Section 16 shows that another linear solver (GMRES, LU) changes only the path to the same ψ.
  • 一阶/二阶开关只改变对流通量的面状态;两种格式的伴随都用同一套代码,验证结果相同。The first/second-order switch changes only the face states of the convective flux; both schemes' adjoints run on the same code, with the same verification.
  • 离散伴随是离散问题的精确导数;它是否趋于连续问题的导数是另一个问题。附录 A 推导并独立求解连续伴随:加密到第 4 级,两种离散伴随与连续伴随给出的导数相互靠近,但相邻两级之比没有稳定在 h2 的 1/4;连续问题在来流与出口交界点、物面角点上有奇性(附录 A.6)。The discrete adjoint is the exact derivative of the discrete problem; whether it approaches the derivative of the continuous problem is another question. Appendix A derives and independently solves the continuous adjoint: refined to level 4, the derivatives from the two discrete adjoints and from the continuous adjoint approach each other, though the ratio between neighbouring levels does not settle at h2's quarter; the continuous problem has singular points where the inflow meets the outlet and at the body's corners (Appendix A.6).
  • 离散伴随的边界条件不是另外写的:它由原始格式在边界上的做法经转置得到。本页的来流处理把连续伴随在来流上不该有的条件带进了离散伴随,所以 ψ 在来流附近趋于另一个问题的解(伴随不一致);导数本身仍是精确的。附录 B 说明原因,伴随一致的版本改掉了它。The discrete adjoint's boundary conditions are not written separately: they are the transpose of what the primal scheme does on the boundary. This page's inflow treatment carries into the discrete adjoint conditions that the continuous adjoint does not have at the inflow, so near the inflow ψ approaches the solution of a different problem (adjoint inconsistency); the derivatives themselves are still exact. Appendix B explains why, and the adjoint-consistent version removes it.

本页不涉及:限制器、激波、SA-neg。

Not on this page: limiters, shocks, SA-neg.

附录 AAppendix A

附录 A:连续伴随

Appendix A: the continuous adjoint

离散伴随(第 8–11 节)给出离散问题的精确导数:每一级网格用的都是同一套代码,本页网格上由点积、前向、复数步长与差分核对。连续伴随回答另一个问题:网格加密时,离散导数是否趋于连续问题的导数。本附录从第 1、4 节的连续问题出发,写出连续伴随方程、边界条件与梯度公式,用与本页离散格式无关的 P1 有限元求解(只有方程的系数取自格点格式的解,A.5),再与两种离散伴随在第 1–4 级网格上比较。方程取自二维可压缩 RANS–SA 的一份完整耦合推导(尚未公开);本附录把用到的每个公式都写出来,读者不需要那份推导稿。五个伴随方程保留标准 SA 的全部模型导数;这个问题特有的来流边界条件与对三个参数的梯度是本页补上的。

The discrete adjoint (Sections 8–11) gives the exact derivative of the discrete problem: every level runs the same code, checked on this page's mesh by the dot test, the tangent, the complex step and finite differences. The continuous adjoint answers a different question: whether the discrete derivatives approach the derivative of the continuous problem as the mesh is refined. This appendix starts from the continuous problem of Sections 1 and 4, writes out the continuous adjoint equations, boundary conditions and gradient formula, solves them by P1 finite elements, a method unrelated to this page's discrete schemes (only the equations' coefficients come from the node scheme's solution, A.5), and compares the result with both discrete adjoints on levels 1–4. The equations come from a full coupled derivation for 2-D compressible RANS–SA (not published yet); this appendix writes out every formula it uses, so the reader needs no access to that derivation. The five adjoint equations keep every model derivative of the standard SA; the inflow boundary conditions of this problem and the gradient with respect to the three parameters are added here.

A.1 连续问题

A.1 The continuous problem

区域 Ω 是第 0 级两圈八边形之间的多边形环。各级网格都在这同一个多边形上逐级细分,所以它的角点也属于连续问题。方程是第 1 节的定常 RANS–SA;边界条件是第 4 节的三种,n 指向区域外:

The domain Ω is the polygonal annulus between the two octagons of level 0. Every level refines this same polygon, so its corners belong to the continuous problem too. The equations are the steady RANS–SA of Section 1, and the boundary conditions the three kinds of Section 4, with n pointing out of the domain:

  • 壁面 Γw:u = v = 0,ν̃ = 0,qn = 0(绝热);the wall Γw: u = v = 0, ν̃ = 0, qn = 0 (adiabatic);
  • 来流 Γin(u∞·n < 0 的面):ρ = 1,u = u∞ = M√γ(cos α, sin α),ν̃ = 3μref,qn = 0,T 自由;the inflow Γin (the faces with u∞·n < 0): ρ = 1, u = u∞ = M√γ(cos α, sin α), ν̃ = 3μref, qn = 0, T free;
  • 出口 Γout:p n − τ·n = p∞n(p∞ = 1),qn = 0,a ∂ν̃/∂n = 0。the outlet Γout: p n − τ·n = p∞n (p∞ = 1), qn = 0, a ∂ν̃/∂n = 0.
CD=eD⋅∫Γwt dsq∞,t=p n−τn,eD=(cos⁡α,sin⁡α),q∞=0.7M2

t 是流体作用在物体上的力的面密度(壁面上 n 指向物体)。设计变量 D 中的三个流动参数 m = (α, M, μref) 经来流数据 u∞(α, M)、ν̃∞ = 3μref、方向 eD(α)、动压 q∞(M) 与粘度 μ(T) = μref·1.4T1.5/(T + 0.4) 进入问题。

t is the surface density of the force the fluid exerts on the body (on the wall n points into the body). The three flow parameters of the design D, m = (α, M, μref), enter through the inflow data u∞(α, M), ν̃∞ = 3μref, the direction eD(α), the dynamic pressure q∞(M), and the viscosity μ(T) = μref·1.4T1.5/(T + 0.4).

A.2 Lagrange 函数与伴随方程

A.2 The Lagrangian and the adjoint equations

给质量、动量、能量三个守恒方程各配一个乘子 λρ、β = (β1, β2)、ζ,给单位质量形式的 SA 方程配乘子 φ,合起来记作连续伴随 λ = (λρ, β, ζ, φ):

Give the mass, momentum and energy conservation equations the multipliers λρ, β = (β1, β2) and ζ, and the SA equation, in its per-unit-mass form, the multiplier φ; together they are the continuous adjoint λ = (λρ, β, ζ, φ):

ℒ=CD+∫Ω(λρRρ+β⋅Rρu+ζRρE+ϕRν~) dΩ
Rν~=u⋅∇ν~−∇⋅(a∇ν~)−cb2σ∣∇ν~∣2−Q

Q 是 SA 的净源项(生成减耗散,第 1 节 S5 的方括号)。第 1 节的守恒形式 SA 方程等于 ρRν̃ + ν̃Rρ,所以离散伴随里 ρν̃ 行的乘子对应 φ/ρ,ρ 行的乘子对应 λρ − ν̃φ/ρ。对状态的每个方向 δW = (δρ, δu, δT, δν̃) 求 ℒ 的一阶变分并分部积分,区域内的系数为零就是五个伴随方程。先记

Q is the SA net source (production minus destruction, the bracket of S5 in Section 1). The conservative SA equation of Section 1 equals ρRν̃ + ν̃Rρ, so in the discrete adjoint the multiplier of the ρν̃ row corresponds to φ/ρ and that of the ρ row to λρ − ν̃φ/ρ. The first variation of ℒ in every direction of the state δW = (δρ, δu, δT, δν̃), integrated by parts, has interior coefficients whose vanishing is the five adjoint equations. With

Qijλ=∂jβi+ui∂jζ,Zij=μe(Qijλ+Qjiλ−23Qkkλδij)
Cμ=Qijλ𝒮ij,Ck=∇ζ⋅∇T,Ht=Cμ+cpPrtCk

(𝒮ij = ∂jui + ∂iuj − ⅔δij∂kuk 是应变率,τ = μe𝒮;Ht 是残差对涡粘性独立变化 δμt 的反向权重),五个方程是(i = 1, 2 是两个速度方程;阻力是壁面上的目标,区域内没有源项)

(𝒮ij = ∂jui + ∂iuj − ⅔δij∂kuk is the strain rate, τ = μe𝒮; Ht is the residual's reverse weight for an independent change δμt of the eddy viscosity), the five equations are (i = 1, 2 are the two velocity equations; the drag is an objective on the wall, so there is no source in the domain)

0=−uj∂jλρ−uiuj∂jβi−T ∂iβi−Huj∂jζ+(μt)ρHt−νρCν0=−ρ∂iλρ−ρuj∂jβi−ρuk∂iβk−ρH∂iζ−ρuiuj∂jζ+τij∂jζ−∂jZij+ϕ ∂iν~+𝒱i0=−ρ ∂iβi−ρcpuj∂jζ−∂j(ke∂jζ)+μTCμ+cpμTPrCk+(μt)THt+μTρCν0=−∇⋅(uϕ)−∇⋅(a∇ϕ)+aν~∇ν~⋅∇ϕ+2cb2σ∇⋅(ϕ∇ν~)−Qν~ ϕ+(μt)ν~Ht
Cν=aν∇ϕ⋅∇ν~−ϕ Qν,Yω=ϕ QΩ sgn ω,(𝒱1,𝒱2)=(−∂yYω, ∂xYω)

Cν 是 SA 残差经分子运动粘度 ν = μ/ρ 反馈到流场的系数,Yω 与 𝒱 是涡量项经分部积分后的形式。a = (ν + ν̃)/σ,所以 aν̃ = aν = 1/σ。其余系数是 SA 模型函数对 ν̃、ν、Ω 的偏导数与涡粘性对状态的偏导数,全部写出如下(不冻结涡粘性,不丢密度梯度项、涡量项与 Sutherland 律)。粘度比与阻尼函数:

Cν is the SA residual's feedback into the flow through the molecular kinematic viscosity ν = μ/ρ, and Yω and 𝒱 are the vorticity term after integration by parts. a = (ν + ν̃)/σ, so aν̃ = aν = 1/σ. The remaining coefficients are the partial derivatives of the SA model functions with respect to ν̃, ν and Ω, and of the eddy viscosity with respect to the state, all written out below (the eddy viscosity is not frozen, and neither the density-gradient term, the vorticity term nor Sutherland's law is dropped). The viscosity ratio and the damping functions:

χν~=1ν,χν=−χν,fv1′=3cv13χ2(χ3+cv13)2,fv2′=χ2fv1′−1(1+χfv1)2,ft2′=−2ct4χft2
Bν~=fv2+χfv2′κ2d2,Bν=−ν~ χfv2′ν κ2d2,BΩ=0

修正的涡量 S̃ = F(Ω, B) 按当地所在的分支求导:第一支 FB = FΩ = 1;第二支(B < −c2Ω)记 N = Ω(c2²Ω + c3B),Ξ = (c3 − 2c2)Ω − B,

The modified vorticity S̃ = F(Ω, B) is differentiated on the branch it sits on: on the first branch FB = FΩ = 1; on the second (B < −c2Ω), with N = Ω(c2²Ω + c3B) and Ξ = (c3 − 2c2)Ω − B,

FB=(c3−c2)2Ω2Ξ2,FΩ=1+(2c22Ω+c3B)Ξ−N(c3−2c2)Ξ2,S~z=FBBz+FΩ δzΩ

z 依次取 ν̃、ν、Ω(δzΩ 是选择符)。r 的截断没有起作用时(r0 < 10,Ir = 1;截断时 Ir = 0),

where z runs over ν̃, ν and Ω (δzΩ selects). Where the cap on r is not active (r0 < 10, Ir = 1; capped, Ir = 0),

rz=Irκ2d2S~(δzν~−ν~S~S~z),gr=1−cw2+6cw2r5,(fw)z=(1+cw36g6+cw36)1/6cw36g6+cw36 gr rz

于是净源项 Q = cb1(1 − ft2)S̃ν̃ − Cdν̃²/d²(Cd = cw1fw − cb1ft2/κ²)的三个偏导数是

so the three partial derivatives of the net source Q = cb1(1 − ft2)S̃ν̃ − Cdν̃²/d² (Cd = cw1fw − cb1ft2/κ²) are

Qz=cb1[(1−ft2)(ν~S~z+S~ δzν~)−ν~S~(ft2)z]−ν~2d2[cw1(fw)z−cb1κ2(ft2)z]−Cd 2ν~d2 δzν~,(ft2)z=ft2′χz

QΩ 既有生成项的,也有经 r → fw 传来的耗散项的导数。涡粘性 μt = ρν̃fv1(χ) 与 Sutherland 粘度的导数:

QΩ carries the derivative of the destruction through r → fw as well as that of the production. The derivatives of the eddy viscosity μt = ρν̃fv1(χ) and of Sutherland's viscosity:

(μt)ν~=ρ (fv1+χfv1′),(μt)ρ=ν~ (fv1+χfv1′),(μt)T=−ρν~ χfv1′ μTμ,μT=dμdT=μ(32T−1T+0.4)

所有系数都取在原始解所在的分支上:S̃ 的两支与 r ≤ 10 的截断按当地取值。这五个方程对 (λρ, β, ζ, φ) 是线性的。

Every coefficient is taken on the branch the primal solution sits on: the two branches of S̃ and the cap r ≤ 10 take their local values. The five equations are linear in (λρ, β, ζ, φ).

A.3 边界条件

A.3 Boundary conditions

分部积分留下的边界项有两部分:𝔟f 来自四个流动方程,𝔟s 来自 SA 方程:

The integration by parts leaves boundary terms in two parts: 𝔟f from the four flow equations and 𝔟s from the SA equation:

𝔟f=un𝒜 δρ+[ρ𝒜n+ρun(β+ζu)+ζt+Zn]⋅δu+[ρcvunζ+ke∂nζ]δT+(β+ζu)⋅δt+ζ δqn
𝔟s=[unϕ+a∂nϕ−2b ϕ ∂nν~]η−ϕ δjs+Yω (nyδu−nxδv)

其中 𝒜 = λρ + β·u + ζE,js = a∂nν̃ 是 SA 的扩散通量,η = δν̃,b = cb2/σ。原始边界条件决定哪些变分为零、哪些自由;自由变分的系数必须为零,这就是伴随边界条件:

with 𝒜 = λρ + β·u + ζE, js = a∂nν̃ the SA diffusive flux, η = δν̃ and b = cb2/σ. The primal boundary conditions decide which variations vanish and which are free; the coefficients of the free ones must vanish, and that is the adjoint boundary condition:

边界boundary原始条件下的变分variations under the primal conditions伴随条件adjoint conditions
壁面wallδu = 0,η = 0,δqn = 0;δρ、δT、δt、δjs 自由,目标里有 eD·t/q∞δu = 0, η = 0, δqn = 0; δρ, δT, δt, δjs free, and the objective holds eD·t/q∞β = −eD/q∞,∂nζ = 0,φ = 0β = −eD/q∞, ∂nζ = 0, φ = 0
出口outletδt = 0,δqn = 0,δjs = 0;δρ、δu、δT、η 自由δt = 0, δqn = 0, δjs = 0; δρ, δu, δT, η free𝒜 = 0;Zn + ρun(β + ζu) + ζp∞n + Yω(ny, −nx) = 0;ke∂nζ + ρcvunζ = 0;a∂nφ + unφ = 0(出口上 js = a∂nν̃ = 0,所以 η 的系数里 −2bφ∂nν̃ 一项为零)𝒜 = 0; Zn + ρun(β + ζu) + ζp∞n + Yω(ny, −nx) = 0; ke∂nζ + ρcvunζ = 0; a∂nφ + unφ = 0 (js = a∂nν̃ = 0 on the outlet, so the term −2bφ∂nν̃ of η's coefficient vanishes)
来流inflowδρ = δu = η = 0,δqn = 0;δT、δt、δjs 自由δρ = δu = η = 0, δqn = 0; δT, δt, δjs freeβ + ζu = 0;ke∂nζ + ρcvunζ = 0;φ = 0β + ζu = 0; ke∂nζ + ρcvunζ = 0; φ = 0

逐项看壁面一行:壁面上 u = 0,所以 un = 0,δρ 的系数 un𝒜 自动为零;δu = 0、η = 0,它们的系数不起作用。δt 自由,它的系数 β + ζu = β 加上目标里的 eD/q∞,给出 β = −eD/q∞;δT 自由,系数 ke∂nζ(un = 0)给出 ∂nζ = 0;η = 0 但 ∂nη 不受约束,所以 δjs = a∂nη 自由,它在 𝔟s 里的系数 −φ 给出 φ = 0。

The wall row term by term: u = 0 on the wall, so un = 0 and the coefficient un𝒜 of δρ vanishes by itself; δu = 0 and η = 0, so their coefficients do not matter. δt is free, and its coefficient β + ζu = β plus the objective's eD/q∞ gives β = −eD/q∞; δT is free, and its coefficient ke∂nζ (un = 0) gives ∂nζ = 0; η = 0 but ∂nη is unconstrained, so δjs = a∂nη is free, and its coefficient −φ in 𝔟s gives φ = 0.

来流一行是本页补上的。若来流给定全部五个量(T 也给定),所有状态的迹都不能变,结论是 β = ζ = φ = 0。这里 T 不给定、热流为零,所以 δT 自由而 δqn = 0;∂nδu 自由,于是 δt 可以取任意值,而且与 δT 无关(给定 δT,仍可用 ∂nδu 把 δt 调成任意值);∂nη 自由,于是 δjs 也可以。这三个自由变分在 𝔟f、𝔟s 里的系数是 β + ζu(δt)、ρcvunζ + ke∂nζ(δT)与 −φ(δjs),令它们为零就是表中的三条。ζ 满足与出口相同的 Robin 条件,β 经 β + ζu = 0 与 ζ 相连。λρ 不需要条件。伴随沿 −u 输运,所以来流边界是伴随的出口:λρ 在那里离开区域;无粘伴随在那里只接受一个条件(原始方程在来流上只有一道出射波),而粘性伴随有四个。这正是原始问题在过定出口上的情形反过来:伴随在来流边界附近有一层边界层,它的厚度就是来流线性化里向区域内增长的那个粘性模态的厚度,正面约 0.15–0.16(附录 B.6;A.6 的图可以看到它)。

The inflow row is added here. If the inflow fixed all five variables (T too), no trace of the state could vary and the result would be β = ζ = φ = 0. Here T is not prescribed and the heat flux is zero, so δT is free and δqn = 0; ∂nδu is free, so δt can take any value, independently of δT (given δT, ∂nδu can still set δt to anything); and ∂nη is free, so δjs can too. In 𝔟f and 𝔟s the coefficients of these three free variations are β + ζu (δt), ρcvunζ + ke∂nζ (δT) and −φ (δjs); setting them to zero gives the three conditions of the table. ζ satisfies the same Robin condition as at the outlet, and β is tied to ζ by β + ζu = 0. λρ takes no condition. The adjoint is transported along −u, so the inflow is the adjoint's outlet: λρ leaves the domain there, and the inviscid adjoint accepts only one condition there (the primal has only one outgoing wave at the inflow), while the viscous adjoint has four. This is the primal problem's over-specified outlet turned around: the adjoint carries a boundary layer next to the inflow, as thick as the viscous mode of the inflow's linearisation that grows into the domain, about 0.15–0.16 on the front faces (Appendix B.6; visible in the figure of A.6).

A.4 梯度

A.4 The gradient

参数变化时状态 W(m) 仍满足边界条件,但来流上的数据变了:δu = ∂u∞/∂m,η = ∂ν̃∞/∂m;其余变分(δT、δt、δjs)的系数已由伴随条件置零。代入 𝔟f、𝔟s,一个伴随解给出三个导数:

As a parameter changes, the state W(m) keeps satisfying the boundary conditions, but the data on the inflow change: δu = ∂u∞/∂m and η = ∂ν̃∞/∂m, while the coefficients of the other variations (δT, δt, δjs) have been set to zero by the adjoint conditions. Put into 𝔟f and 𝔟s, one adjoint solution gives all three derivatives:

dCDdm=∂CD∂m∣W+∫Γin([ρ𝒜n+ρun(β+ζu)+ζt+Zn]⋅∂u∞∂m+a ∂nϕ ∂ν~∞∂m)ds+∫Ω(∂μe∂mCμ+∂ke∂mCk+∂a∂m∇ϕ⋅∇ν~−ϕ Qν∂ν∂m)dΩ

在来流上 φ = 0,所以 Yω 与 η 系数里含 φ 的项都消失。第一项是目标的显式导数:α 经 eD(α),∂CD/∂α|W = eD′·F/q∞(F 是物体受的力,eD′ = (−sin α, cos α));M 经 q∞,∂CD/∂M|W = −2CD/M。μref 也经 t 里的粘性应力进入目标,但这一项与壁面边界项 (β + ζu)·δt 在 β = −eD/q∞ 时正好抵消(来流上 β + ζu = 0 让同类的项为零,出口的牵引力是给定值),所以对 μref 第一项为零,剩下来流上的 a∂nφ ∂ν̃∞/∂μref(ν̃∞ = 3μref)与最后的体积分,体积分里的偏导数在固定状态下取(第 4 级上两者分别是 14.61 与 206.31)。体积分只对 μref 非零:α 与 M 只经来流速度进入问题。

On the inflow φ = 0, so Yω and the terms with φ in η's coefficient drop out. The first term is the objective's explicit derivative: α enters through eD(α), ∂CD/∂α|W = eD′·F/q∞ (F the force on the body, eD′ = (−sin α, cos α)); M through q∞, ∂CD/∂M|W = −2CD/M. μref also enters the objective through the viscous stress in t, but that term cancels exactly against the wall's boundary term (β + ζu)·δt at β = −eD/q∞ (on the inflow β + ζu = 0 removes the same kind of term, and the outlet's traction is prescribed), so for μref the first term is zero; what remains is the inflow term a∂nφ ∂ν̃∞/∂μref (ν̃∞ = 3μref) and the last volume integral, whose partial derivatives are taken at a fixed state (on level 4 they are 14.61 and 206.31). The volume integral is non-zero for μref only: α and M enter the problem only through the inflow velocity.

A.5 离散:P1 有限元

A.5 Discretisation: P1 finite elements

连续伴随用与第 3–11 节无关的办法求解:每一级网格的四边形沿一条对角线分成两个三角形,五个伴随场都取连续分片线性函数(P1),用 Galerkin 弱形式;方程的系数取格点格式在同一级网格上收敛解的 P1 插值。

The continuous adjoint is solved by a method unrelated to Sections 3–11: every quadrilateral of a level is split into two triangles along a diagonal, the five adjoint fields are continuous and piecewise linear (P1), and the weak form is Galerkin; the coefficients come from the P1 interpolant of the node scheme's converged solution on the same level.

  • 二阶项(∇·Z、∇·(ke∇ζ)、∇·(a∇φ)、∇·(φ∇ν̃))与涡量项 𝒱 分部积分到试函数上,所以只用到原始解的一阶导数,sgn ω 的跳跃也精确保留;the second-order terms (∇·Z, ∇·(ke∇ζ), ∇·(a∇φ), ∇·(φ∇ν̃)) and the vorticity term 𝒱 are integrated by parts onto the test function, so only first derivatives of the primal solution appear, and the jump of sgn ω is kept exactly;
  • 稳定化:内部边上的连续内罚 ciphF2 s∫F[∂nw][∂nλ] ds(λρ、β、ζ 取 s = |u·n| + c,φ 取 s = |u·n|,cip = 0.05)。光滑解的法向导数在边上没有跳跃,所以这一项是相容的;stabilisation: the continuous interior penalty ciphF2 s∫F[∂nw][∂nλ] ds on the interior edges (s = |u·n| + c for λρ, β, ζ and s = |u·n| for φ, cip = 0.05). A smooth solution's normal derivative has no jump across an edge, so this term is consistent;
  • 边界:强条件在节点上直接替换方程——壁面 β = −eD/q∞、φ = 0;来流 β + ζu = 0、φ = 0;出口 𝒜 = 0(替换 λρ 的方程)。自然条件进入弱形式:出口的动量与能量 Robin 项,来流的能量 Robin 项;boundaries: the strong conditions replace equations at the nodes: β = −eD/q∞ and φ = 0 on the wall, β + ζu = 0 and φ = 0 on the inflow, and 𝒜 = 0 on the outlet (replacing λρ's equation). The natural conditions enter the weak form: the outlet's momentum and energy Robin terms, and the inflow's energy Robin term;
  • 梯度里的 Zn 与 a∂nφ 不从 λ 的离散边界导数求,而是变分地取:把 ∂u∞/∂m、∂ν̃∞/∂m 放在来流节点上的试函数代入未加强条件的弱形式;the Zn and a∂nφ of the gradient are not taken from the discrete λ's derivative on the boundary but variationally: a test function carrying ∂u∞/∂m and ∂ν̃∞/∂m at the inflow nodes is put into the weak form before the strong conditions are imposed;
  • 线性方程组用稀疏 LU 直接求解。有限体积格式的 A 与 AT 都没有用到——这是两种伴随的比较有意义的前提。the linear system is solved directly by sparse LU. Neither the finite-volume schemes' A nor AT is used anywhere: that is what makes the comparison of the two adjoints meaningful.

A.6 验证

A.6 Verification

方程。弱形式的系数数组写成强形式后,与一个独立实现的强形式比较(它用自己的多项式原始场与乘子,按 A.2 的五个方程直接用 LGL 谱微分求值,阶数 12、20、28):最大相对差 3.0×10−14。两边的 SA 模型函数与它们的偏导数取自同一个函数,所以这一项检验的是方程的组装,不单独检验这些偏导数。

The equations. The weak form's coefficient arrays, written in strong form, are compared with an independent implementation of the strong form (on its own polynomial primal fields and multipliers, evaluating the five equations of A.2 directly with LGL spectral differentiation of orders 12, 20, 28): the largest relative difference is 3.0×10−14. Both take the SA model functions and their partial derivatives from the same routine, so this checks how the equations are assembled, not those partials on their own.

离散。给定解析的原始场、壁面距离与伴随场,把强形式代入得到源项与边界数据,在第 2–5 级网格上求解(制造的场让每个 SA 分支都不切换)。五个分量的 L2 误差:

The discretisation. Given analytic primal fields, wall distance and adjoint fields, the strong form gives the source terms and boundary data, and the problem is solved on levels 2–5 (the manufactured fields keep every SA branch from switching). The L2 errors of the five components:

级levelhλρβ1β2ζφ
20.19097.5×10−33.5×10−33.4×10−32.4×10−38.9×10−4
30.09551.5×10−39.3×10−48.4×10−44.3×10−42.0×10−4
40.04773.3×10−42.3×10−42.1×10−48.4×10−54.8×10−5
50.02397.9×10−55.8×10−55.2×10−51.8×10−51.2×10−5
阶order2.062.002.002.202.04

最后一行是第 4→5 级的阶:都接近 P1 的 2。梯度用到的两个来流泛函也收敛:对流项 ∫(ρ𝒜n + ζt + …)·δu 的相对误差依次为 1.7×10−3、3.7×10−4、8.7×10−5、2.0×10−5;变分取得的通量项 ∫(Zn·δu + a∂nφ δν̃) 依次为 3.1×10−3、2.6×10−4、4.9×10−6、1.4×10−5。这一项只检验连续伴随的 P1 求解器;本页有限体积格式本身的精度阶在第 15 节。

The last row is the order from level 4 to 5: all close to P1's 2. The two inflow functionals of the gradient converge as well: the convective term ∫(ρ𝒜n + ζt + …)·δu with relative errors 1.7×10−3, 3.7×10−4, 8.7×10−5, 2.0×10−5, and the variationally recovered flux term ∫(Zn·δu + a∂nφ δν̃) with 3.1×10−3, 2.6×10−4, 4.9×10−6, 1.4×10−5. This tests the continuous adjoint's P1 solver only; the order of accuracy of this page's finite-volume scheme itself is in Section 15.

连续与离散。同一个连续问题的三种近似:格点、格心两种离散伴随(第 11 节的伴随方程,用第 16 节的 GMRES 求解:较细的格心网格上第 11 节的不动点迭代发散;各级网格上都是离散问题的精确导数)与上面的连续伴随(系数取格点格式的解)。CD 与三个导数随网格加密:

Continuous and discrete. Three approximations of the same continuous problem: the node and cell discrete adjoints (the adjoint equation of Section 11, solved by the GMRES of Section 16, since on the finer cell meshes the fixed point of Section 11 diverges; on every level the exact derivative of the discrete problem) and the continuous adjoint above (its coefficients from the node scheme's solution). CD and the three derivatives under refinement:

级level格点 CDnode CD格心 CDcell CD
054.20036.2300
111.42866.6549
27.27206.6499
36.59356.6457
46.43996.5991
级level连续伴随 dCD/dαcontinuous dCD/dα格点离散伴随node discrete格心离散伴随cell discrete
0—−15.57800.0198
1−4.9993−2.7622−1.6201
2−1.8963−1.5489−1.5277
3−1.5050−1.4173−1.4995
4−1.4259−1.3895−1.4689
级level连续伴随 dCD/dMcontinuous dCD/dM格点离散伴随node discrete格心离散伴随cell discrete
0—−45.1009−12.6542
130.0971−26.3344−13.3136
2−5.7845−15.4486−11.6343
3−10.7072−13.1466−11.6419
4−11.8373−12.7630−11.9406
级level连续伴随 dCD/dμrefcontinuous dCD/dμref格点离散伴随node discrete格心离散伴随cell discrete
0—620.99178.91
1327.78290.68207.50
2252.50236.37218.43
3227.39221.99221.95
4220.92218.27220.58
1e-41e-31e-21e-11e01e11234网格级(每级 h 减半)mesh level (h halves per level)h²hdCD/dαdCD/dMdCD/dμref连续 − 格点continuous − node格心 − 格点cell − node都除以格点值each over the node value
图 A.1 · 实线:连续伴随与本页(格点)离散伴随给出的导数之差;虚线:格心与格点两种离散伴随之差;都相对格点的值。点线是每级缩小到 1/4(h²)与 1/2(h)的参考斜率。连续伴随的系数取格点格式的解,本页离散伴随与它共用原始解;虚线含两种格式原始解之差。Figure A.1 · Solid: the difference between the derivatives from the continuous adjoint and from this page's (node) discrete adjoint; dashed: between the cell and node discrete adjoints; each relative to the node value. The dotted lines are reference slopes of a quarter (h²) and a half (h) per level. The continuous adjoint takes its coefficients from the node scheme's solution, which this page's discrete adjoint shares; the dashed lines carry the difference between the two schemes' primal solutions.

连续伴随与本页(格点)离散伴随给出的导数的相对差(除以格点值,第 1、2、3、4 级):α −81.0% → −22.4% → −6.2% → −2.6%;M 214.3% → 62.6% → 18.6% → 7.3%;μref 12.8% → 6.8% → 2.4% → 1.2%。相邻两级之比:α 0.28、0.28、0.42;M 0.29、0.30、0.39;μref 0.53、0.36、0.50。从第 1 级到第 4 级,三个差分别缩小到原来的 1/31、1/30、1/11,但相邻两级之比没有稳定在 h2 的 1/4;最后一步比前一步慢的是 α、M、μref。第 4 级:格心离散伴随给出 −1.469、−11.941、220.6,本页(格点)给出 −1.389、−12.763、218.3。两种格式与连续伴随的相对差(第 4 级):格心 α 2.9%、M 0.9%、μref 0.2%,格点 α 2.6%、M 7.3%、μref 1.2%;格心格式在 α 上更远,在 M、μref 上更近。连续伴随的系数取自格点格式的解,格点离散伴随与它共用原始解;格心格式的比较还带着两种格式原始解之差(第 4 级 CD:格心 6.5991,格点 6.4399);图中虚线是两种离散伴随之差。相邻两级之比不稳定的原因在连续问题本身:来流与出口交界的两个八边形顶点上,速度的 Dirichlet 条件与牵引力条件相遇,出口一侧的速度偏差 |u − u∞| 按到顶点距离的幂次变化(第 4 级网格上两个交界点拟合的幂次为 0.65、0.67,小于 1),解的梯度在那里无界;物面八边形的角点也是奇点。原始解与伴随在这些点附近都不光滑,离散误差在那里不按光滑解的 h2 规律变化。此外,连续伴随在来流边界上有 A.3 所说的边界层,P1 解要在网格上把它分辨出来。

The relative difference between the derivatives from the continuous adjoint and from this page's (node) discrete adjoint (over the node value, levels 1, 2, 3, 4): α −81.0% → −22.4% → −6.2% → −2.6%; M 214.3% → 62.6% → 18.6% → 7.3%; μref 12.8% → 6.8% → 2.4% → 1.2%. The ratios between neighbouring levels: α 0.28, 0.28, 0.42; M 0.29, 0.30, 0.39; μref 0.53, 0.36, 0.50. From level 1 to level 4 the three differences shrink by factors of 31, 30, 11, but the ratio between neighbouring levels does not settle at a quarter (h2); the last step is slower than the one before for α, M, μref. On level 4 the cell scheme's discrete adjoint gives −1.469, −11.941, 220.6, this page's (node) −1.389, −12.763, 218.3. The two schemes' relative differences from the continuous adjoint on level 4: cell α 2.9%, M 0.9%, μref 0.2%, node α 2.6%, M 7.3%, μref 1.2%; the cell scheme lies further away for α and closer for M, μref. The continuous adjoint takes its coefficients from the node scheme's solution, which the node discrete adjoint shares; the cell scheme's comparison also carries the difference between the two schemes' primal solutions (CD on level 4: cell 6.5991, node 6.4399); the dashed lines are the difference between the two discrete adjoints. Why the ratio does not settle lies in the continuous problem itself: at the two octagon vertices where the inflow meets the outlet, the velocity's Dirichlet condition meets the traction condition, and on the outlet side the velocity deviation |u − u∞| varies as a power of the distance to the vertex (fitted at the two junctions on level 4: powers 0.65, 0.67, below 1), so the solution's gradient is unbounded there; the corners of the body's octagon are singular points too. Near these points neither the primal solution nor the adjoint is smooth, and the discretisation error there does not follow a smooth solution's h2 law. Besides, the continuous adjoint carries the inflow boundary layer of A.3, which the P1 solution has to resolve on the mesh.

伴随场本身。格点格式的残差第 i 行是守恒残差在节点 i 的对偶体上的积分,本页的 Lagrange 函数是 CD + ψTR,与 A.2 的 ℒ 同号,所以 ψi 近似连续伴随在 xi 处的守恒方程乘子(A.2)。边界节点(壁面、来流、出口)不参加比较:强条件行的 ψ 是反作用。离来流边界 0.8 以外的节点上,两者的相对均方根差:

The adjoint fields themselves. Row i of the node scheme's residual is the integral of the conservative residual over node i's dual cell, and this page's Lagrangian CD + ψTR has the sign of A.2's ℒ, so ψi approximates the continuous adjoint's multipliers of the conservative equations at xi (A.2). The boundary nodes (wall, inflow, outlet) are left out: the ψ of a strong row is a reaction. Over the nodes farther than 0.8 from the inflow, the relative RMS difference of the two:

级levelψρ ↔ λρ − ν̃φ/ρψρu ↔ β1ψρv ↔ β2ψρE ↔ ζψρν̃ ↔ φ/ρ
295.1%16.8%21.5%33.4%18.2%
316.9%4.9%6.7%7.6%7.2%
412.7%1.3%2.4%5.8%2.4%
4.79110λρ − ν̃φ/ρ / ψρ−369.28β₁ / ψρu−35−4.94ζ / ψρE−0.530.00φ/ρ / ψρν̃横轴:从来流边界(左)沿网格线到物面(右)horizontal: from the inflow boundary (left) along the mesh line to the wall (right)连续伴随(P1)continuous adjoint (P1)格点离散伴随 ψ(第 4 级)node discrete adjoint ψ (level 4)
图 A.2 · 第 4 级网格上沿 180° 网格线的两种伴随(连续伴随换算到守恒方程的乘子)。强条件行(来流节点、壁面节点被替换的行)的 ψ 是反作用,不画。离来流边界约 0.8 以外两者逐点接近(差别见上表);靠近来流,连续伴随有一层边界层,本页的离散伴随不趋于它:来流节点被替换的行把 λρ = 0 这类条件带进了离散伴随(伴随不一致,附录 B)。Figure A.2 · The two adjoints along the 180° mesh line on level 4 (the continuous adjoint mapped to the multipliers of the conservative equations). The ψ of the strong rows (the replaced rows of the inflow and wall nodes) is a reaction and is not drawn. Beyond about 0.8 from the inflow the two are close node by node (the table above gives the differences); near the inflow the continuous adjoint has a boundary layer, which this page's discrete adjoint does not approach: the replaced rows of the inflow nodes bring conditions such as λρ = 0 into the discrete adjoint (adjoint inconsistency, Appendix B).

动量与 ν̃ 的乘子逐级靠近(第 3→4 级之比 0.27–0.36);质量与能量的乘子收敛得慢一些,它们与来流边界层和出口的 𝒜 = 0 耦合在一起。靠近来流,连续伴随有 A.3 所说的边界层(ζ 与 λρ 向来流陡升;附录 B.6 的线性化给出它在正面的厚度约 0.15–0.16)。本页的格点离散伴随在那里不趋于它:来流节点被替换的行给离散伴随带进了连续伴随在来流上没有的条件 λρ = 0、β = 0,这就是伴随不一致(附录 B)。离散导数仍是离散问题的精确导数,它们随加密靠近连续伴随的导数;但来流附近的 ψ 不能当作 λ 的近似来用。

The multipliers of momentum and ν̃ approach each other level by level (a ratio of 0.27–0.36 from level 3 to 4); those of mass and energy converge more slowly, being coupled to the inflow layer and to the outlet's 𝒜 = 0. Near the inflow the continuous adjoint has the boundary layer of A.3 (ζ and λρ climb steeply towards the inflow; the linearisation of Appendix B.6 gives it a thickness of about 0.15–0.16 on the front faces). This page's node discrete adjoint does not approach it there: the replaced rows of the inflow nodes bring into the discrete adjoint the conditions λρ = 0 and β = 0, which the continuous adjoint does not have at the inflow: adjoint inconsistency (Appendix B). The discrete derivatives are still the exact derivatives of the discrete problem, and they approach the continuous adjoint's under refinement; but near the inflow ψ cannot be used as an approximation of λ.

结论:离散伴随在每一级都是离散问题的精确导数(第 13、14 节);连续伴随是对连续问题导数的另一种近似。从第 1 级到第 4 级,两者的差缩小到原来的 1/31、1/30、1/11(α、M、μref):这是数值上的证据,说明本页的两种离散格式与这个连续问题相容,它们的导数趋于同一个连续灵敏度。

The conclusion: on every level the discrete adjoint is the exact derivative of the discrete problem (Sections 13 and 14), and the continuous adjoint is another approximation of the continuous problem's derivative. From level 1 to level 4 the difference between them shrinks by factors of 31, 30, 11 (α, M, μref): numerical evidence that this page's two discrete schemes are consistent with this continuous problem and that their derivatives approach the same continuous sensitivity.

范围:这里比较的是同一个连续问题(包括它的角点)的几种近似,结论是数值上的。它不证明连续问题解的存在唯一与伴随的正则性;在交界点与角点附近,伴随与原始解一样有奇性,在 ω = 0 或 r0 = 10 处模型本身不可微,那里需要单侧导数(S̃ 两支交界处一阶导数连续)。连续伴随的系数取自格点格式的解,所以它检验的是伴随方程、边界条件与梯度公式,不单独检验原始解。

Scope: what is compared here are several approximations of the same continuous problem (its corners included), and the conclusion is numerical. It does not prove existence and uniqueness for the continuous problem or the regularity of its adjoint; near the junctions and the corners the adjoint is singular like the primal solution, and where ω = 0 or r0 = 10 the model itself is not differentiable and needs one-sided derivatives (the two branches of S̃ meet with a continuous first derivative). The continuous adjoint takes its coefficients from the node scheme's solution, so it tests the adjoint equations, boundary conditions and gradient formula, not the primal solution on its own.

参考文献

References

  • P. R. Spalart, S. R. Allmaras, A one-equation turbulence model for aerodynamic flows, La Recherche Aérospatiale 1 (1994) 5–21。标准 SA 模型。P. R. Spalart, S. R. Allmaras, A one-equation turbulence model for aerodynamic flows, La Recherche Aérospatiale 1 (1994) 5–21. The standard SA model.
  • S. R. Allmaras, F. T. Johnson, P. R. Spalart, Modifications and clarifications for the implementation of the Spalart–Allmaras turbulence model, ICCFD7-1902 (2012)。S̃ 的修正分支与可压缩守恒形式里的密度梯度项。S. R. Allmaras, F. T. Johnson, P. R. Spalart, Modifications and clarifications for the implementation of the Spalart–Allmaras turbulence model, ICCFD7-1902 (2012). The modified branch of S̃ and the density-gradient term of the compressible conservative form.
  • NASA Langley Turbulence Modeling Resource(TMR),The Spalart–Allmaras turbulence model,turbmodels.larc.nasa.gov。本页所用的标准 SA(含 ft2、r ≤ 10)与常数。NASA Langley Turbulence Modeling Resource (TMR), The Spalart–Allmaras turbulence model, turbmodels.larc.nasa.gov. The standard SA used here (with ft2 and r ≤ 10) and its constants.
  • P. L. Roe, Approximate Riemann solvers, parameter vectors, and difference schemes, J. Comput. Phys. 43 (1981) 357–372。Roe 通量。P. L. Roe, Approximate Riemann solvers, parameter vectors, and difference schemes, J. Comput. Phys. 43 (1981) 357–372. The Roe flux.
  • T. D. Economon, F. Palacios, S. R. Copeland, T. W. Lukaczyk, J. J. Alonso, SU2: an open-source suite for multiphysics simulation and design, AIAA J. 54 (2016) 828–846。边式格点格式与修正平均梯度的粘性通量。T. D. Economon, F. Palacios, S. R. Copeland, T. W. Lukaczyk, J. J. Alonso, SU2: an open-source suite for multiphysics simulation and design, AIAA J. 54 (2016) 828–846. The edge-based node scheme and the corrected-average-gradient viscous flux.
  • R. Hartmann, Adjoint consistency analysis of discontinuous Galerkin discretizations, SIAM J. Numer. Anal. 45 (2007) 2671–2696。伴随一致性(附录 B)。R. Hartmann, Adjoint consistency analysis of discontinuous Galerkin discretizations, SIAM J. Numer. Anal. 45 (2007) 2671–2696. Adjoint consistency (Appendix B).
  • T. E. Peterson, A note on the convergence of the discontinuous Galerkin method for a scalar hyperbolic equation, SIAM J. Numer. Anal. 28 (1991) 133–140。纯对流问题上一阶迎风格式的 h1/2 收敛阶(第 15 节)。T. E. Peterson, A note on the convergence of the discontinuous Galerkin method for a scalar hyperbolic equation, SIAM J. Numer. Anal. 28 (1991) 133–140. The rate h1/2 of first-order upwinding on a purely convective problem (Section 15).
附录 BAppendix B

附录 B:伴随一致性

Appendix B: adjoint consistency

本页的来流处理是伴随不一致的;伴随一致的版本只在来流边界上与本页不同。本附录说明两者差在哪里、为什么这一点差别决定离散伴随在来流附近趋于什么,并在同一组网格上比较两者。

This page's inflow treatment is adjoint-inconsistent; the adjoint-consistent version differs from it on the inflow boundary only. This appendix explains the difference, why it decides what the discrete adjoint approaches near the inflow, and compares the two on the same meshes.

B.1 什么是伴随一致

B.1 What adjoint consistency means

两种版本的离散伴随 ψ 都满足 ATψ = −g,都是各自离散问题的精确导数(第 8–14 节的检验对两者都成立)。伴随一致性(也叫对偶一致性)问的是另一件事:把 ATψ = −g 本身看作一个离散格式,它是不是连续伴随方程连同边界条件的相容离散。若是,加密时 ψ 逐点趋于连续伴随 λ(换算到守恒方程的乘子,附录 A.2),边界附近也一样;若不是,ψ 在区域内部仍可以趋于 λ,在边界附近却趋于另一个问题的解。两种版本的区域内部格式、壁面与出口完全相同,连续问题也相同(附录 A.1),所以差别只可能来自来流边界。

The discrete adjoints ψ of both versions satisfy ATψ = −g and are the exact derivatives of their discrete problems (the checks of Sections 8–14 hold for both). Adjoint consistency (also called dual consistency) asks something else: read ATψ = −g itself as a discrete scheme; is it a consistent discretisation of the continuous adjoint equations together with their boundary conditions? If it is, ψ approaches the continuous adjoint λ (mapped to the multipliers of the conservative equations, Appendix A.2) point by point under refinement, next to the boundary as well; if it is not, ψ can still approach λ inside the domain, but next to the boundary it approaches the solution of a different problem. The two versions share the interior scheme, the wall and the outlet, and the continuous problem (Appendix A.1), so any difference comes from the inflow boundary.

B.2 离散伴随的边界条件从哪里来

B.2 Where the discrete adjoint's boundary conditions come from

离散伴随的边界条件不是另外写的:AT 是原始格式的转置,边界上的做法经转置自动变成伴随的边界条件。有两条规则:

The discrete adjoint's boundary conditions are not written separately: AT is the transpose of the primal scheme, and what the scheme does on the boundary turns into the adjoint's boundary conditions by that transpose. Two rules:

  • 被替换的行。替换后的一行 Ri,k = Ui,k −(给定值) 只依赖节点自己的 Ui,k(一致版本的来流行还依赖 Ui,ρ)。它的乘子 ψi,k 只出现在自己那一列的伴随方程里(一致版本的来流行还以 −W∞,kψi,k 出现在 ρ 那一列),是一个反作用;其余伴随方程看被替换之前的那一行,就像它的乘子是 0。所以替换一行,等于给其余的离散伴随加上“这个分量在这个节点为零”。壁面节点的动量行是一个例外:它们也被替换了,但第 7 节的阻力取的正是它们被替换之前的值,CD = −eD·Σ Ri动量/q∞。在 Lagrange 函数里,这两行因此带着乘子 −eD/q∞ 而不是 0;其余伴随方程看到的是 β = −eD/q∞,正是 A.3 表中壁面的条件(照搬“为零”就会得到 β = 0,那是错的)。数值上:把 ψ 在壁面节点的动量分量换成 −eD/q∞、ν̃ 分量换成 0 以后,替换之前各遍的转置在所有未被替换行触及的列上都为零(相对 g 的最大分量 9.0×10−16);离壁面最近一排节点的 ψρu 平均值逐级 −13.3、−24.0、−29.7(第 2、3、4 级),趋向 −cos α/q∞ = −35.6。Replaced rows. A replaced row Ri,k = Ui,k − (given value) depends on the node's own Ui,k only (the consistent version's inflow rows on Ui,ρ as well). Its multiplier ψi,k appears in its own column's adjoint equation only (the consistent version's inflow rows also, as −W∞,kψi,k, in the node's ρ column) and is a reaction; every other adjoint equation sees the row as it was before the replacement as if its multiplier were 0. So replacing a row imposes on the rest of the discrete adjoint “this component is zero at this node”. The wall nodes' momentum rows are the exception: they are replaced too, but the drag of Section 7 takes exactly their values before the replacement, CD = −eD·Σ Rimomentum/q∞. In the Lagrangian these two rows therefore carry the multiplier −eD/q∞, not 0, and every other adjoint equation sees β = −eD/q∞: exactly the wall condition of A.3's table (taking “zero” literally would give β = 0, which is wrong). Numerically: with ψ's momentum components on the wall nodes replaced by −eD/q∞ and its ν̃ component by 0, the transpose of the passes before the replacement vanishes in every column that no replaced row reaches (at most 9.0×10−16 of g's largest entry); the mean ψρu of the first row of nodes off the wall is −13.3, −24.0, −29.7 on levels 2, 3, 4, approaching −cos α/q∞ = −35.6.
  • 边界通量依赖的状态分量。边界半面的通量 Fbc 读哪些状态分量,AT 在这些分量的列上就多出 (∂Fbc/∂U)Tψ。连续问题在来流上的通量只经温度 T 和牵引力、SA 扩散通量这些自由的量依赖解:ρ、u、ν̃ 是给定值。离散通量若还依赖节点的 ρ、u 或 ν̃,转置后就多出连续伴随没有的边界项。The state components a boundary flux reads. Whatever state components the boundary half-face's flux Fbc reads, AT receives (∂Fbc/∂U)Tψ in those columns. The continuous inflow flux depends on the solution only through the temperature T and the free quantities traction and SA diffusive flux: ρ, u and ν̃ are given. If the discrete flux also reads the node's ρ, u or ν̃, its transpose carries boundary terms the continuous adjoint does not have.

连续伴随在来流上要满足的是附录 A.3 的三条,λρ 不需要条件:伴随沿 −u 输运,来流边界是 λρ 离开区域的地方。换算到守恒方程的乘子(A.2):ψρ ↔ λρ − ν̃φ/ρ,ψρu ↔ β,ψρE ↔ ζ,ψρν̃ ↔ φ/ρ。

What the continuous adjoint has to satisfy on the inflow are the three conditions of Appendix A.3, and λρ takes none: the adjoint is transported along −u, and the inflow is where λρ leaves the domain. In the multipliers of the conservative equations (A.2): ψρ ↔ λρ − ν̃φ/ρ, ψρu ↔ β, ψρE ↔ ζ, ψρν̃ ↔ φ/ρ.

β+ζu=0,ke ∂nζ+ρcvunζ=0,ϕ=0

B.3 原来的来流处理为什么伴随不一致

B.3 Why the original inflow treatment is adjoint-inconsistent

格点格式原来把来流节点的 ρ、ρu、ρv、ρν̃ 四行替换成 U − U∞,能量行保留。按规则 1,其余伴随方程在来流节点上看到 ψρ = ψρu = ψρv = ψρν̃ = 0,也就是说离散伴随在来流上满足

The node scheme originally replaced an inflow node's ρ, ρu, ρv and ρν̃ rows by U − U∞ and kept its energy row. By rule 1 every other adjoint equation sees ψρ = ψρu = ψρv = ψρν̃ = 0 at an inflow node: on the inflow the discrete adjoint satisfies

λρ=0,β=0,ϕ=0
  • φ = 0 与连续条件相同。φ = 0 agrees with the continuous condition.
  • β = 0 与 β = −ζu 不同,而 ζ 在来流上并不为零(第 4 级网格上 180° 顶点处 λ 的 ζ = −35.2)。能量行虽然保留,它在来流半面上的功 u·τn 用的是节点自己梯度给出的牵引力,不是动量行的反作用,所以 A.3 里组成 β + ζu 的两项在离散里凑不到一起。β = 0 differs from β = −ζu, and ζ is not zero on the inflow (λ's ζ = −35.2 at the 180° vertex on level 4). The energy row is kept, but the work u·τn on its inflow half-faces uses the traction of the node's own gradients, not the momentum rows' reaction, so the two terms that form β + ζu in A.3 never meet in the discrete equations.
  • λρ = 0 是连续伴随没有的条件:λρ 在伴随的出口被钉住。这正是原始问题在出口多给一个条件的伴随版。结果是来流附近根本没有 A.3 的那一层:第 4 级 180° 网格线上离来流 0.055 的节点,ψρ = 12.3,λ 的对应值是 85.0(B.5 的剖面图)。λρ = 0 is a condition the continuous adjoint does not have: λρ is pinned at the adjoint's outlet. This is the adjoint version of giving the primal problem one condition too many at an outlet. The result is that the layer of A.3 is missing next to the inflow altogether: on level 4, at the node 0.055 from the inflow on the 180° mesh line, ψρ = 12.3 where λ gives 85.0 (the profiles of B.5).

B.4 伴随一致的来流处理

B.4 The adjoint-consistent inflow treatment

一致的版本改三处。质量行保留:ρ 只经来流半面上给定的质量通量 ρ∞u∞·n 进入,这一项不依赖任何状态,λρ 不受约束。ρu、ρv、ρν̃ 三行替换成 Uk − UρW∞,k(以节点自己的 ρ 给定 u、ν̃),ψρν̃ 的行被替换,φ = 0 照旧。能量行在替换之前减去 u∞ 乘两行动量行。来流半面只带对流通量,所以替换前动量行的值 ℳi 正是经来流半面作用在节点上的粘性牵引力 Fi(反作用);这一步就是把下面的混合形式里的 Fi 消去:

The consistent version changes three things. The mass row stays: ρ enters only through the given mass flux ρ∞u∞·n on the inflow half-faces, which depends on no state, so λρ is left free. The ρu, ρv and ρν̃ rows become Uk − UρW∞,k (u and ν̃ given at the node's own ρ); ψρν̃'s row is replaced, so φ = 0 as before. And the energy row subtracts u∞ times the two momentum rows before they are replaced. The inflow half-faces carry convection only, so the momentum rows' values ℳi at that point are exactly the viscous traction Fi on the node through them (the reaction); the step eliminates Fi from the mixed form

ℳi−Fi=0,ℰi−u∞ ⁣⋅Fi=0⟹ℰi−u∞ ⁣⋅ℳi=0

ℳi、ℰi 是不含来流半面粘性项的动量与能量平衡。把 Fi 当作未知量,它那一列的伴随方程是 ψM + u∞ψE = 0:这就是离散的 β + ζu = 0。能量平衡里来流半面没有热流,半面对流通量里压力 ρ∞Tin 与 ρ∞cpTiun 经这个组合合成 ρ∞cvunTi,转置后给出 Robin 条件里的 ρcvunζ。代码上只多两步:第 4 遍先做能量行的组合,再替换三行(第 5、9 节的演示逐句执行它们)。

ℳi and ℰi are the momentum and energy balances without the inflow half-faces' viscous terms. With Fi as an unknown, its column's adjoint equation is ψM + u∞ψE = 0: the discrete β + ζu = 0. The energy balance has no heat flux through the inflow half-faces, and in their convective flux the pressure ρ∞Tin and ρ∞cpTiun combine through this step into ρ∞cvunTi, whose transpose is the ρcvunζ of the Robin condition. In the code this is two extra steps: pass 4 combines the energy row first and then replaces the three rows (the demos of Sections 5 and 9 execute them statement by statement).

图 B.1 把附录 B 的转置规则落到本页的一个来流半面上:对流通量对节点状态 Wi = (ρ, u, v, T, ν̃) 的 Jacobian 有哪些非零列,转置后的边界项就落在哪些方向。原来的处理有 5 列非零(ρ、u、v、T、ν̃),伴随一致的处理只有 1 列(T)。格点页原来的处理还替换了来流节点的 ρ、ρu、ρv、ρν̃ 四行:第 4 遍之后只剩能量行用到半面通量,ρ、u、v 列属于被替换的分量,它们的伴随方程只给反作用,原处理的不一致来自被替换的行(附录 B 的规则 1、B.3)。粘性部分两种处理也不同:原处理的来流半面减去节点梯度给出的粘性通量(能量行里有功 u·τn),一致的处理没有粘性项(B.4);图里不画。

Figure B.1 applies Appendix B's transpose rule to one inflow half-face of this page: the non-zero columns of the convective flux's Jacobian with respect to the node state Wi = (ρ, u, v, T, ν̃) are the directions in which the transposed boundary terms land. The original treatment has 5 non-zero columns (ρ, u, v, T, ν̃), the adjoint-consistent one 1 (T). On the node page the original treatment also replaces the inflow node's ρ, ρu, ρv and ρν̃ rows: after pass 4 only the energy row uses the half-face's flux, and the ρ, u, v columns belong to replaced components, whose adjoint equations give reactions only, so the original's inconsistency comes from the replaced rows (rule 1 of Appendix B, B.3). The viscous part differs too: the original half-face subtracts the viscous flux of the node's gradients (the work u·τn in its energy row), the consistent one has none (B.4); it is not in the figure.

(a) 原来的来流处理(a) the original inflow treatment非零列:ρ、u、v、T、ν̃non-zero columns: ρ, u, v, T, ν̃−0.05−0.280.6700−0.40−0.120.16−0.2800.94−6e−3−0.040.670−0.26−1.393.33−0.180−3e−3−0.020.040−0.05ρρuρvρEρν̃ρuvTν̃(b) 伴随一致的来流处理(b) the adjoint-consistent inflow treatment非零列:Tnon-zero columns: T00000000−0.2800000.670000−0.18000000ρρuρvρEρν̃ρuvTν̃行:对流通量的五个分量;列:来流节点状态 Wi 的五个原始变量rows: the five components of the convective flux; columns: the five primitives of the inflow node's state Wi紫框:T 列violet frame: the T column
图 B.1 · 附录 B 的转置规则画在本页 U* 的一个来流半面上:对流通量对节点状态 Wi 的 Jacobian。(a) 原来的处理(节点自己状态的物理通量)有 5 列非零,但节点的 ρ、ρu、ρv、ρν̃ 行在第 4 遍被替换,只有能量行留下;原处理的不一致来自被替换的行(附录 B 的规则 1)。(b) 伴随一致的处理取边界状态 (ρ∞, u∞, v∞, T, ν̃∞) 的物理通量,只有 T 一列非零:转置后的边界项只在温度方向,正是连续伴随的来流条件所允许的。Figure B.1 · Appendix B's transpose rule on one inflow half-face of this page, at U*: the Jacobian of the convective flux with respect to the node state Wi. (a) The original treatment (the node's own physical flux) has 5 non-zero columns; but the node's ρ, ρu, ρv and ρν̃ rows are replaced in pass 4 and only the energy row survives: the original's inconsistency comes from the replaced rows (rule 1 of Appendix B). (b) The adjoint-consistent treatment takes the physical flux of the boundary state (ρ∞, u∞, v∞, T, ν̃∞) and has only the T column: the transposed boundary term lies in the temperature direction alone, which is what the continuous adjoint's inflow conditions allow.

B.5 数值比较

B.5 The numbers

两种版本各自的连续伴随(系数取同一版本格点格式的解)与离散伴随逐级比较。下表是离来流边界 0.3 以内的节点(边界上的节点不计)上 ψ − λ 的相对均方根;离来流 0.8 以外两种版本相差无几(第 4 级:ψρ 13% 与 13%,ψρE 6% 与 6%)。

The two versions' discrete adjoints against their continuous adjoints (with the same version's node solution as coefficients), level by level. The table gives the relative RMS of ψ − λ over the nodes within 0.3 of the inflow boundary (the boundary nodes themselves left out); beyond 0.8 from it the two versions are alike (level 4: ψρ 13% and 13%, ψρE 6% and 6%).

级level原处理 ψρoriginal ψρ原处理 ψρEoriginal ψρE一致 ψρconsistent ψρ一致 ψρEconsistent ψρE
296%69%82%56%
393%59%48%29%
486%53%23%14%
1e-21e-11e0234网格级(每级 h 减半)mesh level (h halves per level)h伴随一致adjoint-consistent原远场original far fieldψρ ↔ λρ − ν̃φ/ρψρE ↔ ζ来流 0.3 以内within 0.3 of the inflow离来流 0.8 以外beyond 0.8 from it
图 B.2 · 格点格式两种远场处理的离散伴随 ψ 与连续伴随 λ 的相对均方根差(λ 换算到守恒方程的乘子,边界节点不计)。实线:离来流边界 0.3 以内;虚线:0.8 以外。点线是每级减半(h)的参考斜率。Figure B.2 · The relative RMS difference between the discrete adjoint ψ and the continuous adjoint λ (mapped to the multipliers of the conservative equations; the boundary nodes left out) for the two far-field treatments of the node scheme. Solid: within 0.3 of the inflow boundary; dashed: beyond 0.8. The dotted line is a reference slope halving per level (h).

一致的版本每加密一级,来流附近的误差约减半(第 3→4 级之比 ψρ 0.48、ψρE 0.47,一阶);原来的版本几乎不动(0.93、0.89):ψρ 96%→93%→86%,它趋于的是另一个问题的解。下图沿 180° 网格线看同一件事:一致版本的 ψ 跟着连续伴随在来流附近的那一层走,原来的版本没有这一层。

The consistent version roughly halves its error next to the inflow with each level (from level 3 to 4 the ratios are 0.48 for ψρ and 0.47 for ψρE: first order); the original barely moves (0.93 and 0.89): ψρ 96%→93%→86%, approaching the solution of a different problem. The figure below shows the same along the 180° mesh line: the consistent ψ follows the layer of the continuous adjoint next to the inflow, while the original has no such layer.

4.81100.00.350.7λρ − ν̃φ/ρ / ψρ−35−5.10.00.350.7ζ / ψρE横轴:从来流边界沿 180° 网格线的距离horizontal: distance from the inflow boundary along the 180° mesh line连续伴随 λcontinuous λ伴随一致 ψconsistent ψ原远场 ψ(第 4 级)original ψ (level 4)
图 B.3 · 第 4 级网格上,从来流边界沿 180° 网格线进入区域的前 0.7:连续伴随(实线,取伴随一致版本的原始解作系数)与两种远场处理的离散伴随。来流节点上被替换的行的 ψ 是反作用,不画。Figure B.3 · The first 0.7 into the domain from the inflow boundary along the 180° mesh line, on level 4: the continuous adjoint (solid, with the consistent variant's primal solution as its coefficients) and the discrete adjoints of the two far-field treatments. The ψ of a replaced row on an inflow node is a reaction and is not drawn.

导数本身在两种版本里都是精确的。第 4 级网格上两种版本的 CD、格点离散伴随给出的导数,以及同一版本连续伴随与它的相对差(除以离散值,与附录 A 相同):

The derivatives themselves are exact in both versions. On level 4, the two versions' CD, the derivatives from the node discrete adjoint, and the same version's continuous adjoint's relative difference from them (over the discrete value, as in Appendix A):

CDdCD/dα与连续伴随之差vs continuousdCD/dM与连续伴随之差vs continuousdCD/dμref与连续伴随之差vs continuous
原处理(本页)original (this page)6.4399−1.38952.6%−12.76307.3%218.31.2%
一致consistent6.4560−1.40490.8%−12.67404.4%219.00.6%

伴随一致性管的是 ψ 在边界附近趋于什么,不直接决定导数误差的大小:导数误差还来自原始解本身、交界点与角点的奇性(附录 A.6)。格点格式上一致的版本离连续伴随的导数更近。

Adjoint consistency governs what ψ approaches next to the boundary; it does not by itself set the size of the derivative's error, which also comes from the primal solution and from the singular points at the junctions and the corners (Appendix A.6). On the node scheme the consistent version's derivatives are closer to the continuous adjoint's.

B.6 两个侧面:来流几乎与边界平行

B.6 The two side faces: inflow almost along the boundary

远场八边形上的四个来流面并不一样:正面(135°–225°)|u∞·n| = 0.210–0.226,两个侧面(90°–135°、225°–270°)只有 0.071–0.109。侧面上两种版本的原始解不同。原处理把来流节点的 ρ 直接取为 ρ∞ = 1;一致的版本只给质量通量,侧面上边界节点的 ρ 最低 0.988、0.974、0.968、0.967(第 1、2、3、4 级),正面上都在 1 的 0.3% 以内。在 96° 处沿法向进入区域 0.36:原处理 ρ 从 1 降到 0.970、T 从 1.027 升到 1.056;一致的版本 ρ 在 0.962–0.969 之间,T 几乎不变。两者从第 3 级到第 4 级都不再变化。

The four inflow faces of the far octagon are not alike: on the front (135°–225°) |u∞·n| = 0.210–0.226, on the two side faces (90°–135° and 225°–270°) only 0.071–0.109. On the side faces the two versions' primal solutions differ. The original sets the inflow nodes' ρ to ρ∞ = 1 directly; the consistent version gives the mass flux only, and on the side faces its boundary nodes' ρ drops to 0.988, 0.974, 0.968, 0.967 (levels 1, 2, 3, 4), while on the front all stay within 0.3% of 1. Going 0.36 into the domain along the normal at 96°: the original's ρ falls from 1 to 0.970 while T rises from 1.027 to 1.056; the consistent version's ρ stays between 0.962 and 0.969 with T nearly constant. Neither changes any more from level 3 to level 4.

原因在连续问题里:把定常 Navier–Stokes 方程沿来流边界的法向线性化,亚声速来流上恰有一个离开边界衰减的粘性模态,厚度约 4μe|un|/(3p):本页的数值是侧面 0.0022–0.0034、正面 0.0066–0.0071。在这一层里 ρ 变化而 ρun 与 T 几乎不变;本页任何一级网格都分辨不了它(最细的网格第 4 级,贴来流边界的第一排节点离边界 0.045)。于是层外的解看到的边界条件取决于离散怎样跨过这一层:原处理把 ρ = ρ∞ 放在边界节点上,一致的版本只给跨层不变的质量通量。同一个线性化的另一个模态朝区域内增长,厚度 0.15–0.47:它就是连续伴随在来流边界上的那一层(A.3)。附录 A 的连续伴随按光滑解推导,没有这一薄层;两种版本都在同一组网格上与它比较,结论只针对这些网格上的解与伴随。

The cause is in the continuous problem: linearise the steady Navier–Stokes equations along the normal of the inflow boundary, and a subsonic inflow has exactly one viscous mode that decays away from the boundary, of thickness about 4μe|un|/(3p): here 0.0022–0.0034 on the side faces and 0.0066–0.0071 on the front. Across this layer ρ changes while ρun and T stay nearly constant, and no mesh of this page resolves it (on the finest mesh, level 4, the first row of nodes lies 0.045 from the inflow boundary). So what boundary condition the solution outside the layer sees depends on how the discretisation steps across it: the original puts ρ = ρ∞ on the boundary node, the consistent version gives only the mass flux, which does not change across the layer. The same linearisation's other mode grows into the domain, with thickness 0.15–0.47: it is the continuous adjoint's layer at the inflow boundary (A.3). The continuous adjoint of Appendix A is derived for a smooth solution and has no thin layer; both versions are compared with it on the same meshes, and the conclusions are about the solutions and adjoints on these meshes.

参考:R. Hartmann, Adjoint consistency analysis of discontinuous Galerkin discretizations, SIAM J. Numer. Anal. 45 (2007) 2671–2696。伴随一致性是 h → 0 的性质;两种版本在每一级网格上都给出离散问题的精确导数,本页前面各节的点积、前向、复数步长与差分检验对两者都成立。

Reference: R. Hartmann, Adjoint consistency analysis of discontinuous Galerkin discretizations, SIAM J. Numer. Anal. 45 (2007) 2671–2696. Adjoint consistency is a property of the limit h → 0; on every mesh both versions give the exact derivative of their discrete problem, and the dot-product, tangent, complex-step and finite-difference checks of this page's earlier sections hold for both.