方程:可压缩 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 = 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:
其中 (取 、、,所以 ),(Sutherland),湍流粘度 ,,
with (, , , so ), (Sutherland), the eddy viscosity with , and
、、。源项只在第 5 个方程里,是 NASA TMR 给出的 SA 守恒形式(密度梯度项不能丢):
, , . 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):
模型函数取标准(非负)版本:
The model functions are the standard (not the negative) version:
Ω = |∂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 页面解同一个连续问题:格心、格点两种控制体,各有两种来流边界的离散;同一种控制体的两个页面只在来流边界的离散上不同。本页沿用原来的处理:来流面用 Roe 通量,外侧放一个取来流 ρ、u、v、ν̃ 的虚拟状态;伴随一致的版本里,来流面取边界状态的物理通量,质量通量就是给定的 ρ∞u∞·n,不加 Roe 耗散。两者都给出各自离散问题的精确导数;区别在于加密时离散伴随在来流附近是否趋于连续伴随(伴随一致性)。做法见第 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 inflow faces take the Roe flux against a ghost state holding the free stream's ρ, u, v and ν̃; in the adjoint-consistent version the inflow faces take the physical flux of the boundary state, whose mass flux is the given ρ∞u∞·n, with no Roe dissipation. 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 = 6.2300,这张粗网格上的阻力有多准见第 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 = 6.2300; Section 7 discusses how accurate the drag of this coarse mesh is. Figure 1.1 draws all of this.
本页的流动: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 不给定,热也会向上游传到那里)。这样的网格分辨不了真实的高雷诺数边界层;这里要的是一个用得到模型各个分支、又能收敛到舍入误差的离散问题:S̃ 的修正分支与 r 的截断(第 4 节列出本页网格上用到它们的控制体数),以及涡粘性:来流状态 χ = 3,μt/μ = 0.21;本页(第 0 级网格)各控制体上 μt/μ 最大 0.087(χ 最大 2.38):χ = ν̃/ν,ν = μ/ρ;区域里 ν̃ 不超过来流值,而 ν 处处至少是来流的 1.05 倍,所以 χ 比来流小。
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 node scheme's solution) 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 modified branch of S̃ and the cap on r (Section 4 counts the control volumes of this page's mesh that use them), 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.087 (χ at most 2.38): χ = ν̃/ν with ν = μ/ρ, and inside the domain ν̃ does not exceed its inflow value while ν is everywhere at least 1.05 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.
在本课程里,二维非结构网格上 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.
本页要回答的问题
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.
网格:单元、面与壁面距离
Mesh: cells, 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.
网格与二维对流页面完全相同,编号也相同:节点逐圈从壁面向外,单元逐圈编号,面按“内部、壁面、远场”排序。未知量放在单元里:24 个单元就是 24 个控制体。区别在于每个控制体现在有 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 in the cells: the 24 cells are the 24 control volumes. The difference is that every control volume now carries 5 unknowns instead of 1.
一个面循环要读的几何量都画在下图里。和标量页面相比多了两样:从控制体中心 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).
壁面距离
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.
逐步推导:壁面距离与它对坐标的导数
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:
第二步,截到线段上。ξ* ≤ 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
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)):
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 = (1/k)ΣnXn,所以 ∂di/∂xi = nw 平分给单元的 k 个顶点,每个 nw/k;Xa、Xb 是壁面节点,各得到第三步的一项。
Step 5, back to the node coordinates. On the cell page the centre is the average of the cell's vertices, xi = (1/k)ΣnXn, so ∂di/∂xi = nw is shared equally by the cell's k vertices, nw/k each; Xa and Xb are wall nodes and receive the terms of Step 3.
核对:本页 24 个中心里,16 个的最近点在边内,8 个在顶点上;对每个 di,第三至第五步的公式与 geometry() 的磁带反向扫描给出的 ∂di/∂X 最大相对差 6.2×10−16(本页代码在构建时计算)。
Check: of this page's 24 centres, 16 have their nearest point inside an edge and 8 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 6.2×10−16 (computed by this page's code at build time).
网格与几何量到这里就齐了。第 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.
面上的通量
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):
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 节)。
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).
每个面仍是一个一维问题: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 平均(以 √ρ 加权:ρ̃ = √(ρ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.
两道声波(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).
逐步推导: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)):
所以对 φ = 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
第三步,求波强。把跳跃写成 Δ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:
动量里剩下的 ρ̃(Δ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):
第二式来自 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
最后一项与跳跃 Δ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.
核对:本页全部 32 个内部面上(U* 处的二阶面状态),Jc(W̃)rk = Λkrk 的相对残差最大 2.7×10−16;ΣkΔkrk 重建跳跃 ΔU 到 9.5×10−14;𝓡|Λ|𝓡−1ΔU 与 model.js 的耗散相差 3.3×10−14;Roe 性质 F(UR) − F(UL) = Jc(W̃)ΔU 成立到 4.5×10−14;|J̃c| 的 ρν̃ 行与列符合第四步到 4.1×10−18。第五步被丢掉的最后一项(一阶、中心状态)占磁带给出的 ∂Φ/∂UL 的比例(Frobenius 范数):最大 5.7%,中位数 1.4%(本页代码在构建时计算)。
Check: on all 32 interior faces of this page (the second-order face states at U*), Jc(W̃)rk = Λkrk holds to a relative residual of at most 2.7×10−16; ΣkΔkrk rebuilds the jump ΔU to 9.5×10−14; 𝓡|Λ|𝓡−1ΔU agrees with model.js's dissipation to 3.3×10−14; Roe's property F(UR) − F(UL) = Jc(W̃)ΔU holds to 4.5×10−14; and the ρν̃ row and column of |J̃c| follow Step 4 to 4.1×10−18. The last term dropped in Step 5 (first order, centre states) is at most 5.7% of the taped ∂Φ/∂UL (Frobenius norm), 1.4% 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:
模板是面相邻的单元。贴壁单元还有一个“壁面点”(壁面面的中点),那里 u = v = ν̃ = 0 已知;ρ 与 T 在绝热壁上不知道,所以贴壁单元用两组权重:u、v、ν̃ 用含壁面点的一组,ρ、T 用只含邻居的一组。两组都对线性场精确。远场面不进入模板。二阶格式把中心值沿 xf − xi 外推:W+ = Wi + Gi·(xf − xi),不加限制器(流动无激波);一阶格式直接取 W+ = Wi。粘性通量与 SA 源项在两种格式里都用这些梯度,所以一阶/二阶开关只改变对流通量;壁面面与来流面例外:它们的粘性系数 μ(T) 用重构到面上的温度 Tw、Tf,一阶时取单元值。
The stencil is the face neighbours. A wall cell also has a “wall point” (its wall face's midpoint), where u = v = ν̃ = 0 are known; ρ and T are not known on an adiabatic wall, so a wall cell has two weight sets: u, v and ν̃ use the one with the wall point, ρ and T the one with the neighbours only. Both are exact for linear fields. Far-field faces take no part in any stencil. 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; the wall and inflow faces are the exception: their viscous coefficients μ(T) use the reconstructed face temperature Tw, Tf (the cell's at first order).
逐步推导:最小二乘梯度、它的权重与转置
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):
第二步,法方程。对 G 求梯度并令其为零:
Step 2, the normal equations. Set the gradient with respect to G to zero:
𝒩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):
权重 Γ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
贴壁单元的两组权重各自满足这个恒等式:u、v、ν̃ 用的一组含壁面点(那里 Wj = 0 已知),ρ、T 用的一组只含邻居。
A wall cell's two weight sets satisfy it each: the one for u, v, ν̃ includes the wall point (where Wj = 0 is known), the one for ρ and T only the neighbours.
第五步,前向与转置。Γ 是线性的,前向就是同一组权重作用在 上;伴随把它转置,梯度 Gi 的伴随 按累加送回整个模板:
Step 5, the tangent and the transpose. Γ is linear, so the tangent applies the same weights to ; the adjoint transposes it, and the adjoint of the gradient Gi goes back over the whole stencil as accumulations:
两者是同一个双线性型 按两种次序求和(core.js applyAT 的 “pass 1 reversed”);两个方向画在图 3.3 (b) 里。
Both are the same bilinear form , summed in two orders (core.js applyAT's “pass 1 reversed”); both directions are drawn in Figure 3.3 (b).
第六步,对坐标的前向导数(第 12 节用)。Δxij 随中心移动,;由 ,
Step 6, the forward derivative with respect to the coordinates (used in Section 12). Δxij moves with the centres, ; with ,
核对:本页 32 组权重(邻居个数:8 个控制体有 2 个、16 个控制体有 3 个,贴壁单元另有壁面点):第三步的 Γij 与 mesh.js 算出的权重最大相对差 0;ΣjΓijΔxijT 与 I 相差 5.6×10−16;一个线性场的梯度误差 6.7×10−16;沿一个随机坐标方向,第六步的 与几何磁带的前向扫描相差 3.5×10−15;随机向量上 与 相差 2.2×10−16(本页代码在构建时计算)。
Check: this page's 32 weight sets (neighbours: 8 control volumes have 2, 16 control volumes have 3, and the wall cells also have the wall point): the Γij of Step 3 and mesh.js's weights differ by at most 0; ΣjΓijΔxijT differs from I by 5.6×10−16; a linear field's gradient is off by 6.7×10−16; along a random coordinate direction, Step 6's and a forward sweep of the geometry's tape differ by 3.5×10−15; and on random vectors and differ by 2.2×10−16 (computed by this page's code at build time).
粘性通量:边上的修正平均梯度
The viscous flux: the corrected average gradient on the edge
逐步推导:修正平均梯度与粘性通量的线性化
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:
第二步,替换沿 Δ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φ 对它的四个输入都是线性的:
Step 3, the derivatives of the face gradient. ∇fφ is linear in each of its four inputs:
两侧的梯度只经过“垂直于 Δ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:
这里 ∇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)
第六步,链式法则(前向模式)。τ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
能量与 ν̃ 两行同理,按乘积法则逐项加点:
The energy and ν̃ rows follow the same way, a dot on each factor in turn by the product rule:
局部磁带记下的正是这些乘积:面核对 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.0×10−16;每个控制体上,viscosity() 与 eddy() 的磁带给出的 μT 与第五步三个偏导数与公式相差 6.9×10−16(本页代码在构建时计算)。
Check: on every interior face of this page, the taped derivatives of corrected() and Step 3's formulas differ by 2.0×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 6.9×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.
逐步推导: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:
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:
第二步,χ = ν̃/ν = ρν̃/μ:
Step 2, χ = ν̃/ν = ρν̃/μ:
第三步,三个阻尼函数只依赖 χ(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′):
第四步,B = ν̃fv2/(κ²d²)。ν̃ 既直接出现,又经 χ 出现,而 ν̃·∂χ/∂ν̃ = χ;ρ 与 T 只经 χ 进入:
Step 4, B = ν̃fv2/(κ²d²). ν̃ appears directly and through χ, with ν̃·∂χ/∂ν̃ = χ; ρ and T enter through χ only:
第五步,涡量。ω = ∂v/∂x − ∂u/∂y 取自最小二乘梯度 Gi,Ω = |ω|:
Step 5, the vorticity. ω = ∂v/∂x − ∂u/∂y comes from the least-squares gradients Gi, and Ω = |ω|:
第六步,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:
在接缝 B = −c2Ω 处 Ξ = (c3 − c2)Ω,第二支的分式等于 −c2Ω:两支的值都是 (1 − c2)Ω,FB 与 FΩ 也都等于 1,所以 S̃ 在接缝处一阶连续。于是 。本页求源项的 24 个控制体里,第二支在 8 个上起作用。
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 . Of this page's 24 control volumes, the second branch is active in 8.
第七步,r 与截断。r0 = ν̃/(κ²d²S̃);未截断时
Step 7, r and its cap. r0 = ν̃/(κ²d²S̃); uncapped,
截断时 r = 10 是常数,:那里 fw 对任何输入都没有导数。本页 7 个控制体被截断。
When capped, r = 10 is a constant and : there fw has no derivative with respect to any input. On this page 7 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:
第九步,净源项。把以上各层代进 Q():
Step 9, the net source. Put the layers above into Q ():
第十步,守恒形式的两项。密度梯度项 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:
第十一步,装配 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.
核对:把上面十一步照写成代码(enrich_data.js 的 saHand,不调用 model.js 的源项),在 U* 的每个求源项的控制体(24 个)上与 model.js source() 的磁带比较:16 个导数的最大相对差 4.6×10−14,源项值 5.6×10−16。其中第二支 8 个、r 截断 7 个、生成项为负(ft2 > 1)9 个(本页代码在构建时计算)。
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 (24 of them) at U*: the 16 derivatives differ by at most 4.6×10−14 (relative), the source's value by 5.6×10−16. Among them 8 are on the second branch, 7 capped, and 9 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 is the subject of Section 4.
边界条件
Boundary conditions
内圈:弱条件的无滑移绝热壁
Inner ring: the no-slip adiabatic wall, weakly
壁面面的通量里没有质量、能量与 ν̃ 的对流(u = 0);动量通量是壁面压力 pw = ρwTw(ρw、Tw 是单元自己重构到壁面的值;一阶格式直接取单元值)减去粘性应力;能量通量为零(绝热,且 uw = 0 时应力不做功);ν̃ 方程有扩散通量 ρa ∇ν̃·n 流向壁面,因为壁面上 ν̃ = 0。
The wall face's flux carries no convection of mass, energy or ν̃ (u = 0); the momentum flux is the wall pressure pw = ρwTw (ρw, Tw are the cell's own reconstruction to the wall; the first-order scheme takes the cell values) minus the viscous stress; the energy flux is zero (adiabatic, and the stress does no work where uw = 0); the ν̃ equation has a diffusive flux ρa ∇ν̃·n into the wall, since ν̃ = 0 there.
外圈:远场
Outer ring: the far field
来流面的 Roe 通量右侧放虚拟状态 Wg = (ρ∞, u∞, v∞, Tf, ν̃∞),Tf 是面状态自己的温度(T 不给定):入射的熵波、剪切波、声波与 ν̃ 波取 Wg 的值,出射声波取单元的值,所以不强加压力。粘性通量沿中心到面点取两点差,面点上 u、v、ν̃ 是来流值;没有热流,功项用 u∞。h → 0 时粘性通量把 u、v、ν̃ 固定在来流值,Roe 通量的熵波把 ρ 也固定下来(两侧温度相同时它的强度是 (1 − 1/γ)(ρ∞ − ρ))。出口面:面状态的对流通量,压力换成 p∞ = 1,能量通量里是 p∞u·n(牵引力做的功),没有粘性通量。
An inflow face puts the ghost state Wg = (ρ∞, u∞, v∞, Tf, ν̃∞) on the right of the Roe flux, Tf being the face state's own temperature (T is not prescribed): the incoming entropy, shear, acoustic and ν̃ waves take Wg's values and the outgoing acoustic wave the cell's, so no pressure is imposed. The viscous flux takes the two-point difference from the centre to the face point, where u, v and ν̃ are the free stream's; there is no heat flux, and the work term uses u∞. As h → 0 the viscous flux holds u, v and ν̃ at the free stream, and the entropy wave of the Roe flux holds ρ as well (with equal temperatures on the two sides its strength is (1 − 1/γ)(ρ∞ − ρ)). An outlet face: the face state's convective flux with its pressure replaced by p∞ = 1, p∞u·n in the energy flux (the work of the traction), and nothing viscous.
在解处冻结的分支
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 ω = 0 | min|ω| / max|ω| = 0.026 | min|ω| / max|ω| = 0.026 |
| Roe 的 |q̃| 在 q̃ = 0 | Roe's |q̃| at q̃ = 0 | min|q̃| = 5.8×10−4 | min|q̃| = 5.8×10−4 |
| S̃ 的两个分支 B = −c₂Ω | the two branches of S̃, B = −c₂Ω | min |B + c₂Ω| / Ω = 0.121(该处一阶导数连续) | min |B + c₂Ω| / Ω = 0.121 (the first derivative is continuous there) |
| r 的截断 r = 10 | the cap r = 10 | min |r₀ − 10| / 10 = 0.144(fw 在 r = 10 已饱和,导数 ~10⁻³¹) | min |r₀ − 10| / 10 = 0.144 (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 |
修正分支在 8 个控制体上起作用,r 在 7 个控制体上被截断:两个分支都真的在用。
The modified branch is active in 8 control volumes and r is capped in 7: both branches are really in use.
下面的演示把这些分支画出来: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. How far the points sit from a switch is the margin of the table above.
残差 = 几遍循环:原始变量、梯度、面、源项
The residual = passes: primitives, gradients, faces, source
标量页面的残差是一个面循环。这里一个面要读两侧的梯度,而梯度要读整个模板的值,所以残差分成几遍:先把所有控制体的原始变量算出来,再算所有梯度,然后才是面通量和源项。
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.
π 在每个控制体上独立地把守恒变量换成原始变量;Γ 是线性的最小二乘算子(权重只依赖几何);F 是面通量的装配,S 是源项。下面的演示逐句执行这几遍:410 步,可以用上方的按钮直接跳到某一遍。
π 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: 410 steps, and the buttons above it jump straight to a pass.
最后一步 max|R| 在舍入误差量级:U* 是收敛解。
At the last step max|R| is at round-off: U* is the converged solution.
求解: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 的一行不只连到邻居,还连到邻居的邻居:200 个非零块。
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: 200 non-zero blocks.
近似 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 是薄剪切层矩阵乘上两点系数 θf = nf·Δx/|Δx|²:动量行 θfμe(I + ⅓n̂n̂T),能量行加上功与导热 θfke,ν̃ 行 θfρa。(ρν̃, ρν̃) 对角元再加上 SA 源项对 ρν̃ 的导数,只在它为正(耗散占优、使对角增强)时加;对角块还加上伪时间项 V/Δt。P 有 88 个非零块。
Θ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. P has 88 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:
第三步,Δ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
第四步,能量与 ν̃ 两行。功 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̂):
第五步,Θ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 相差 5.0×10−16(相对 Frobenius 范数)。本页的面并不正交:32 个内部面上 Δx 与 n 的夹角平均 17.9°,最大 40.1°(本页代码在构建时计算)。
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 5.0×10−16 (relative, Frobenius norm). This page's faces are not orthogonal: over the 32 interior faces the angle between Δx and n is 17.9° on average and 40.1° 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).
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:
把 AΔU 移到左边,就是每一步要解的线性方程:
Moving AΔU to the left gives the linear system of each step:
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:
一次对称扫描是 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.
算例的状态
The state of the test case
二阶格式在第 514 次迭代满足判据(每个方程按自身尺度的残差都小于 10−13),然后继续到舍入底 1.8×10−15;一阶格式在第 46 次(这些是构建页面时在 Node.js 里测得的;页首的状态行是你的浏览器重算的,舍入底的末位可能不同)。收敛解处 ρ 在 [0.901, 1.000],p 在 [0.971, 1.094],ν̃ 最小 0.00437(来流 0.0600):处处为正,标准 SA 不需要任何截断。
The second-order scheme meets the criterion (every equation's residual, scaled by its own size, below 10−13) at iteration 514 and runs on to the round-off floor 1.8×10−15; the first-order scheme at iteration 46 (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.901, 1.000], p in [0.971, 1.094], and ν̃ is at least 0.00437 (free stream 0.0600): positive everywhere, and the standard SA needs no clipping.
图 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.
目标函数:阻力系数
The objective: the drag coefficient
F 是流体作用在物体上的力。格心页上它就是所有壁面面的动量通量之和:弱条件的通量本身就是壁面上的压力减去粘性应力。
F is the force the fluid exerts on the body. On the cell page it is the sum of the wall faces' momentum fluxes: the weak condition's flux is itself the wall pressure minus the viscous stress.
粗网格的阻力有多准
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 volumes | CD |
|---|---|---|---|---|
| 0 | 24 | 6.2300 | ||
| 1 | 96 | 6.6549 | ||
| 2 | 384 | 6.6499 |
第 0 级的阻力与第 2 级相差 6%:这张教学网格只有 8 个面贴着物体。附录 A 把两种格式都算到第 4 级:格心 6.599,格点 6.440,两者还差 2.5%。从第 0 级到第 4 级,本页的 CD 变化 +5.9%,三个导数:dCD/dα 变号(0.0198 → −1.469)、dCD/dM −5.6%、dCD/dμref +23%;其中对 α、μref 的导数比阻力变得多(第 12 节、附录 A)。本页关心的是离散问题的导数:它在每一级网格上都是那一级离散问题的精确导数,但第 0 级的值不能当作连续问题导数的近似。
The level-0 drag differs from level 2's by 6%: this teaching mesh has only 8 faces on the body. Appendix A takes both schemes to level 4: cell 6.599, node 6.440, still 2.5% apart. From level 0 to level 4 this page's CD changes by +5.9%, and its three derivatives: dCD/dα changes sign (0.0198 → −1.469), dCD/dM by −5.6%, dCD/dμref by +23%; the derivatives with respect to α and μref 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 的右端。它只在贴壁单元(及其最小二乘模板里的单元)上非零。本页把整个目标函数录成一条磁带,反向扫描一次得到它:种子 ,扫描返回的 就是 g。
g = ∂CD/∂U is the right-hand side of the adjoint equation ATψ = −g. It is non-zero only on the wall cells (and the cells in their least-squares stencils). This page gets it from one reverse sweep of a tape of the objective: with the seed the sweep returns .
逐步推导: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 cell page F is the sum of the wall faces' momentum fluxes: the wall pressure comes from the wall cells' reconstruction, the stress from their corrected gradient. α and M enter the inflow data only, and no wall face touches the inflow, so at fixed U, F does not depend on α or M; μref enters the viscous stress.
第二步,α。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:
第三步,M。q∞ = 0.7M²,dq∞/dM = 2q∞/M:
Step 3, M. q∞ = 0.7M², dq∞/dM = 2q∞/M:
第四步,μ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 χ = ρν̃/μ:
格心页把它加在每个壁面面上(μe 是贴壁单元与壁面点的平均,壁面上 μt = 0):
The cell page sums it over the wall faces (μe averaged between the wall cell and the wall point, with μt = 0 on the wall):
没有涡粘性时,这就是 CD 的粘性部分除以 μref:固定流场时粘性应力与 μref 成正比。涡粘性使它变小:固定 ν̃ 时 μref 增大,χ 减小,μt 也减小。
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 就在哪些控制体上非零:壁面压力 ρwTw 读贴壁单元与它 ρ、T 模板里的邻居,壁面应力读贴壁单元的修正梯度,也就是它 u、v 模板里的邻居。图 7.2 画出 g。
Step 5, g = ∂CD/∂U. g is non-zero exactly in the control volumes whose state F reads: the wall pressure ρwTw reads the wall cell and the neighbours of its ρ, T stencil, and the wall stress reads the wall cell's corrected gradient, that is, the neighbours of its u, v stencil. Figure 7.2 draws g.
核对:本页 CL = −0.757400,与整条磁带给出的 ∂CD/∂α|U = −0.757400 相对差 0;
Check: on this page CL = −0.757400, and the whole-residual tape gives ∂CD/∂α|U = −0.757400, a relative difference of 0; −2CD/M = −62.2997 against the tape's −62.2997, 1.1×10−16; Step 4's sum is 115.4415 against the tape's 115.4415, 1.2×10−16. g is non-zero in 16 control volumes (computed by this page's code at build time).
matrix-free 前向:计算
Matrix-free forward mode: computing
为什么需要 A 与 AT 的乘积
Why products with A and AT are needed
对任何设计变量 D(迎角、马赫数、参考粘度、每个节点坐标),
For any design variable D (the angle of attack, the Mach number, the reference viscosity, each node coordinate),
前向每个设计变量解一次,伴随解一次就得到所有设计变量的导数。两种迭代都只需要一个动作:(residual_d)或 (residual_b)。
The tangent needs one solve per design variable, the adjoint one solve for all of them. Both iterations need only one action: (residual_d) or (residual_b).
记号:点与横线
Notation: the dot and the bar
从这里起,对离散代码的求导都用自动微分的记号(Griewank 与 Walther): 是程序变量 x 的前向(切线)导数, 是它的反向(伴随)导数;反向把语句倒过来执行,累加写作 ,前向里被覆盖的量清零,。两个求解的结果沿用本页的名字 v 与 ψ:
From here on, every derivative of the discrete code is written in the notation of algorithmic differentiation (Griewank and Walther): is the forward (tangent) derivative of a program variable x, its reverse (adjoint) derivative; reverse mode runs the statements backwards, accumulating, , and zeroing what the forward code overwrote, . The two solves keep this page's names, v and ψ:
的显式部分 ∂CD/∂D 来自目标的反向扫描(种子 ;第 7 节的 g 就是这种扫描对 U 给出的 )。最后一行是对偶恒等式:第 9 节的点积检验在随机向量上核对它,第 11 节前向与伴随的导数估计逐步相等是它在迭代上的形式。
The explicit part ∂CD/∂D of comes from a reverse sweep of the objective with (Section 7's g is the 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_b ≡ :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 ≡ and x_b ≡ : 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* 处对每个核录一次磁带(一个内部面最多 1032 个节点),反向扫 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 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 1032 nodes for an interior face) and sweeps it backwards 5 times for its 5×30 local Jacobian Jf.
装配:同样的几遍
Assembly: the same passes
为什么这正是
Why this is exactly
链式法则: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
演示最后一步把循环的结果 R_d 与显式的 A·U_d 相比(A 由 120 次同样的 residual_d 逐列拼出,只为对照)。随机向量的点积检验(第 9 节)也验证了这一点:两者之差 7.4×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 7.4×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/∂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):
第三步,结构。Π 是下三角矩阵,对角元 1、1/ρ、1/ρ、1/(ρcv)、1/ρ 在 ρ > 0 时都不为零,所以它可逆。前向的第 0 遍是每个控制体一次 ,伴随的最后一步是 ;ΠT 是上三角的, 的 ρ 分量收集 全部五个分量的贡献。
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 once per control volume, and the last step of the adjoint is ; ΠT is upper triangular, and the ρ component of gathers contributions from all five components of .
核对:在 U* 的每个控制体上,上面的 Π 与 model.js prim() 的磁带相差 2.1×10−16(相对)(本页代码在构建时计算)。
Check: in every control volume of U*, the Π above and the tape of model.js prim() differ by 2.1×10−16 (relative) (computed by this page's code at build time).
逐步推导:每一遍的前向语句
Step by step: the tangent statement of every pass
前向模式把程序的每一句 y = φ(x) 换成 ,语句的顺序不变,程序覆盖的量,前向也覆盖。下表把第 5 节 residual 的每一遍与 residual_d 的对应语句并排列出(上面演示里的清单执行的就是这组语句):左列在 U* 处取值,右列只多了点。
Forward mode replaces every statement y = φ(x) of the program by , 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.
| 遍 | pass | residual | residual_d |
|---|---|---|---|
| 0 原始变量 | 0 primitives | ||
| 1 最小二乘梯度 | 1 least-squares gradients | ||
| 2 面状态(二阶) | 2 face states (second order) | ||
| 2 面通量 | 2 face flux | ||
| 2 分发 | 2 scatter | ||
| 3 SA 源项 | 3 SA source |
ΔxLf = xf − xL 与 ΔxRf = xf − xR 是从两侧中心到面点的重构方向(下标从起点到终点,与最小二乘模板的 Δxij = xj − xi 一样),一阶格式 W+ = W,没有这一行。roe′、visc′ 是两个核各自的局部 Jacobian;第 8 节的 Jf 是整个面核,把重构也算在里面,所以 就是上表面状态与面通量两行合起来。壁面、来流、出口面的核在第 9 节与它们的伴随一起推导。每一句的点只作用在它读的状态上:Γ、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 is the table's face-states and face-flux rows together. The kernels of the wall, inflow and outlet faces are derived in Section 9 together with their adjoints. 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.
逐句求前向导数,就是 residual_d 在一个面上执行的语句,顺序相同:
Differentiating statement by statement gives what residual_d executes on one face, in the same order:
(3) 把 √ρ 的前向导数 代进了商的求导法则;(6) 里 。(8) 里特征向量的前向导数按它们的分量逐个加点:
(3) puts the tangent of √ρ, , into the quotient rule; in (6) . In (8) the eigenvectors' tangents take a dot on each entry:
sgn Λk 是当前解所在那一支的符号:本页是亚声速流,声波的 q̃ ∓ c̃ 离零很远,q̃ 离零多远由第 4 节列出;在那一支上 |Λk| 是光滑的。粘性核的前向语句就是第 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. 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.
核对:在本页全部 32 个内部面上,沿随机方向,上面九句前向语句给出的 与 model.js roe() 的复数步长(步长 10−30)最大相对差 7.6×10−16;粘性核的前向语句 4.6×10−16;整个面核(重构、Roe 减粘性)2.9×10−15;壁面面 3.7×10−16、来流面 1.1×10−15、出口面 6.9×10−16;两种来流处理的核在本页状态上 4.8×10−16;SA 源项(24 个控制体,连 d 一起)2.0×10−15;原始变量 4.9×10−16。把这些语句按上表拼成 residual_d,与 core.js 的 applyA(局部磁带)相差 6.0×10−16,与残差的中心差分(步长 10−6)相差 1.9×10−10(本页代码在构建时计算)。
Check: on all 32 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 7.6×10−16 (relative); the viscous kernel's tangent statements by 4.6×10−16; the whole face kernel (reconstruction, Roe minus viscous) by 2.9×10−15; the wall faces by 3.7×10−16, the inflow faces by 1.1×10−15 and the outlet faces by 6.9×10−16; both inflow treatments' kernels at this page's state by 4.8×10−16; the SA source (24 control volumes, d included) by 2.0×10−15; the primitives by 4.9×10−16. Assembled into residual_d as in the table, the statements agree with core.js's applyA (local tapes) to 6.0×10−16 and with a central difference of the residual (step 10−6) to 1.9×10−10 (computed by this page's code at build time).
图 8.4 把这些语句放到网格上执行: 取第 10 节的前向解 v(迎角方向,),面一个接一个地把 分给两侧,源项一个接一个地加到 ρν̃ 行上,每个控制体的五个分量随之累加。扫到最后 :α 只经来流数据进入残差,所以 f 只在带来流面的单元上不为零,其余控制体上各个面与源项的贡献相消(到求解判据 10−13)。
Figure 8.4 runs these statements on the mesh: is Section 10's tangent solution v (along the angle of attack, ), the faces one after another send 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 : α enters the residual only through the inflow data, so f is non-zero only at the cells with an inflow face, and everywhere else the faces' and sources' contributions cancel (to the solve's criterion, 10−13).
matrix-free 伴随:计算
Matrix-free adjoint mode: computing
转置一个乘积要把因子倒过来、每个因子转置。反向把第 8 节的几条语句倒过来执行,从种子 出发:
Transposing a product reverses the factors and transposes each. Reverse mode runs the statements of Section 8 backwards, from the seed :
- 面与源项的转置:原来“写 R[L]、R[R]”的地方变成“读 ”,一个 5 维权重经 JfT 变成 30 个,累加到 与 上。The transpose of the faces and the source: where R[L] and R[R] were written, is read, and one 5-vector of weights becomes 30 through JfT, accumulated into and .
- 最小二乘的转置 Γ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 转置乘法,累加到 上。The transpose of the primitives, ΠT: one 5×5 transposed product per control volume, accumulated into .
点积检验
The dot-product test
取随机的 与 :如果 residual_b 真是 residual_d 的转置,第 8 节的对偶恒等式两边应在舍入误差内相等:
Take random and : if residual_b really is the transpose of residual_d, the two sides of Section 8's duality identity agree to round-off:
图 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.
核对:五处的内积最大相对差 1.3×10−15;两端与 core.js 的 applyA、applyAT 算出的 = −1.204、 = −1.204 一致(本页代码在构建时计算)。
Check: the five inner products differ by at most 1.3×10−15 (relative); the two ends agree with = −1.204 and = −1.204 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) 换成 ,整段程序从最后一句倒着执行;前向里覆盖了某个量的语句,在反向里先把这个量的伴随交出去,再把它清零()。下表按反向执行的顺序排列:第 3 遍最先,第 0 遍最后;每一行的右列是左列那一句的转置。
Reverse mode replaces every statement y = φ(x) by 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 (). The table lists the statements in the order reverse mode runs them, pass 3 first and pass 0 last; the right column of each row is the transpose of its left column.
| 遍 | pass | residual | residual_b(按表的顺序执行) | residual_b (run in the table's order) |
|---|---|---|---|---|
| 3 SA 源项 | 3 SA source | |||
| 2 分发 | 2 scatter | |||
| 2 面通量 | 2 face flux | |||
| 2 面状态(二阶) | 2 face states (second order) | |||
| 1 最小二乘梯度 | 1 least-squares gradients | |||
| 0 原始变量 | 0 primitives |
累加是因为一个量被几句读到,它的伴随就要收集几份:Wi 被它自己的面状态、它所在的每个最小二乘模板、它的每个面和它自己的 SA 源项读到,所以 在这四处都有 +=。Js,i 是源项核 Visi 的局部 Jacobian(第 8 节),所以除以 Vi 与 里的 Vi 抵消。
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 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 .
逐步推导:Roe 核的伴随语句
Step by step: the adjoint statements of the Roe kernel
把第 8 节的九句倒过来:从 出发,(9) 最先、(1) 最后;每一句把它左边那个量的伴随按偏导数分给右边的每个输入,一个输入被几句读到就收集几份。跳跃的伴随 与质量通量的伴随 是中间量:(5) 把前者 + 给 R 侧、
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 are intermediates: (5) sends the former to the R side with + and to the L side with −.
(3)、(2)、(1) 对 R 侧同样各有一组。(8) 的 还要按特征向量的分量送回 Roe 平均量( 是它的两个动量分量):r1、r2、r3 都给 与 ;r1,3 里的 ∓c̃n̂ 与 H̃ ∓ q̃c̃ 给 、、(上面的符号属于 k = 1);r2 的能量分量 ½(ũ² + ṽ²) 给 。按 model.js 的写法,它们与 (8) 的各行在同一段代码里完成。图 9.5 在一个面上逐句执行第 8 节的前向与这里的反向,每一句的值、点与横线都标出来。
(3), (2) and (1) have the same set for the R side. The of (8) still has to go back to the Roe averages entry by entry ( is its two momentum entries): r1, r2 and r3 all give and ; the ∓c̃n̂ and H̃ ∓ q̃c̃ of r1,3 give , and (the upper sign for k = 1); r2's energy entry ½(ũ² + ṽ²) gives . 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.
核对:在本页 32 个内部面上,用随机的 与 ,这组伴随语句与第 8 节的前向语句满足 ,最大差 3.5×10−16(相对各乘积的绝对值之和);它们给出的 与 roe() 局部磁带的反向扫描相差 3.5×10−16(本页代码在构建时计算)。
Check: on the 32 interior faces of this page, with random and , these adjoint statements and the tangent statements of Section 8 satisfy to 3.5×10−16 (relative to the sum of the products' sizes); the they give and a reverse sweep of roe()'s local tape differ by 3.5×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,所以从 出发;下标 ρ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 ; the subscripts ρu, ρE, ρν̃ are Fv's components, and a subscript L,R stands for one statement on each side:
第一行的 把动量行与能量行里的同一个 τ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 源项推导的十一步)倒着执行,从 出发。FB、FΩ、ft2′、fv2′ 与 μT 是第 3 节第一至第八步的偏导数;、 是 ∂v/∂x、∂u/∂y 在 里的分量:
The SA source (the eleven steps of Section 3's SA derivation) runs backwards from . FB, FΩ, ft2′, fv2′ and μT are the partials of Steps 1 to 8 of Section 3; and are the entries of for ∂v/∂x and ∂u/∂y:
r 被截断时它是常数 10,这一处的 不往下传。每个输入收集了几份:ν̃ 经 a、Q、r、B、χ 五处,d 经 Q、r、B 三处(第 12 节把 经壁面距离交给坐标)。前向第十一步里 −ρQ 对 ρ 的导数是 −Q − ρ∂Q/∂ρ,在这里就是第一行的 与经 χ、ν 回来的那一份。
Where r is capped it is the constant 10 and its 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 on to the coordinates through the wall distance). The −Q − ρ∂Q/∂ρ of the forward Step 11 is here the of the first line plus the share that comes back through χ and ν.
核对:在本页 32 个内部面上,粘性核的伴随语句与它的前向语句满足点积恒等式,最大差 2.7×10−16(相对各乘积的绝对值之和),与 viscous() 局部磁带的反向扫描相差 4.1×10−16;在求源项的 24 个控制体上,SA 源项的伴随语句与前向语句 5.5×10−16,与 source() 的磁带 5.6×10−14;原始变量的 与 1.6×10−16(本页代码在构建时计算)。
Check: on the 32 interior faces of this page the viscous kernel's adjoint and tangent statements satisfy the dot-product identity to 2.7×10−16 (relative to the sum of the products' sizes) and agree with a reverse sweep of viscous()'s local tape to 4.1×10−16; in the 24 control volumes where the source is evaluated the SA source's adjoint and tangent statements to 5.5×10−16 and source()'s tape to 5.6×10−14; the primitives' and to 1.6×10−16 (computed by this page's code at build time).
逐步推导:壁面面、来流面与出口面
Step by step: the wall, inflow and outlet faces
壁面面。壁面状态取单元自己的重构 Ww(一阶时取单元值),壁面点上 u = v = ν̃ = 0,Δx = xf − xL:
The wall face. The wall state is the cell's own reconstruction Ww (the cell's values at first order), u = v = ν̃ = 0 at the wall point, and Δx = xf − xL:
它的前向语句逐项加点(,;壁面点的值是常数,它的点为零)。伴随语句从 出发,中间一段是上面粘性核伴随语句的第三至第五行(系数取壁面这一对平均, 是第五行里壁面那一侧的 ):
Its tangent statements put a dot on each factor (, ; the wall point's value is a constant with no dot). Its adjoint statements start from , with the third to fifth lines of the viscous kernel's adjoint above in the middle (with the wall's pair of averages; is the fifth line's on the wall's side):
壁面点的值没有伴随可接收。目标函数的反向扫描用的也是这组语句,只是种子换成 :每个壁面面上 、,再经 ΓT、ΠT 就是第 7 节的 g。
The wall point's value has no adjoint to receive. The objective's reverse sweep uses these same statements with the seed : on every wall face and , and through ΓT and ΠT that is Section 7's g.
来流面。面状态 Wf = WL + GL·Δx(一阶时取单元值),边界状态 Wbc = (ρ∞, u∞, v∞, Tf, ν̃∞) 只从面状态取温度。通量是对流部分减粘性部分,Φ = Φc − Fv,Fv = (0, τn, u∞·τn, ρa∇fν̃·n),两种处理的粘性部分相同。本页的残差在来流面上用原来的处理(第 4 节);伴随一致的版本用另一种,下面把两种一并写出,好对照。原来的处理 Φc = roe(Wf, Wg),Wg 是第 4 节的虚拟状态(数值上就是 Wbc):它的前向语句就是 Roe 的 (1)–(9),取 、;伴随语句 (9)→(1) 给出的两侧伴随按下式交回面状态。伴随一致的处理取边界状态的物理通量:
The inflow face. The face state is Wf = WL + GL·Δx (the cell's values at first order), and the boundary state Wbc = (ρ∞, u∞, v∞, Tf, ν̃∞) takes only the temperature from it. The flux is convective minus viscous, Φ = Φc − Fv with Fv = (0, τn, u∞·τn, ρa∇fν̃·n), the same viscous part in both treatments. This page's own residual takes the original treatment on the inflow faces (Section 4); the adjoint-consistent version takes the other, and both are written out below for comparison. The original treatment has Φc = roe(Wf, Wg), Wg being Section 4's ghost state (the same values as Wbc): its tangent statements are Roe's (1)–(9) with and , and the two sides' adjoints of its adjoint statements (9)→(1) go back to the face state as below. The adjoint-consistent treatment takes the boundary state's physical flux:
原来的处理里,Roe 伴随语句给出 WL 侧的全部五个分量与 WR 侧的温度: 收下前者, 再收下后者,对流部分的转置落在面状态的全部分量上。伴随一致的处理只经 Tf 依赖单元,转置只有上面温度那一句。粘性部分在两种处理里都一样:
In the original treatment the Roe adjoint statements give all five components on the WL side and the temperature on the WR side: takes the former and the latter as well, and the transpose of the convective part lands on every component of the face state. The adjoint-consistent treatment reads the cell only through Tf, and its transpose is the temperature statement above alone. The viscous part is the same in both:
牵引力 τn 同时出现在动量行与能量行的功里,所以同一个组合 进入 :这就是附录 B 的 β + ζu。图 9.6 把两种处理在本页每个来流面上的这些数并排画出来。出口面:面状态的物理通量,压力换成 p∞,Φ = ρq(1, u, v, E, ν̃) + p∞(0, nx, ny, q, 0),q = u·n;它的前向与伴随语句与 Roe 核 (1)、(2) 在一侧的那几句相同,只是 H 换成 E、压力换成常数 p∞,能量分量多一项 p∞q(前向 )。
The traction τn appears in the momentum rows and in the energy row's work, so the same combination enters : Appendix B's β + ζu. Figure 9.6 draws these numbers for both treatments, side by side, on every inflow face of this page. The outlet face: the face state's physical flux with the pressure replaced by p∞, Φ = ρq(1, u, v, E, ν̃) + p∞(0, nx, ny, q, 0) with q = u·n; 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 ).
核对:壁面面 8 个、来流面 4 个、出口面 4 个:这些伴随语句与前向语句的点积恒等式最大差 4.4×10−16,与 core.js 面核的局部磁带 JfT 相差 5.3×10−16;两种来流处理的核在本页状态上满足点积恒等式到 3.2×10−16。整个伴随那一遍与 core.js 的 applyAT 相差 3.8×10−16;图中对流部分的伴随另由 model.js 通量的磁带反向扫描算出,相差 2.1×10−16(本页代码在构建时计算)。
Check: 8 wall, 4 inflow and 4 outlet faces: these adjoint statements and the tangent ones satisfy the dot-product identity to 4.4×10−16 and agree with the local tapes of core.js's face kernels, JfT, to 5.3×10−16; both inflow treatments' kernels at this page's state satisfy the identity to 3.2×10−16. The whole adjoint pass agrees with core.js's applyAT to 3.8×10−16; the figure's convective adjoints, recomputed by a reverse sweep of a tape of model.js's flux, differ by 2.1×10−16 (computed by this page's code at build time).
算例:一个内部面、一个壁面面、一个来流面
A worked example: one interior face, one wall face, one inflow face
用本页的数把上面的语句走一遍。前向的种子取第 10 节的前向解,(v 是第 10 节的那个向量,不是速度分量 v;迎角方向,;前向在第 501 次迭代满足判据),伴随的种子取第 11 节的伴随解,。
The statements above, walked through with this page's numbers. The tangent's seed is Section 10's tangent solution, (v is that vector, not the velocity component v; along the angle of attack, ; the tangent meets its criterion at iteration 501), and the adjoint's seed is Section 11's adjoint, .
内部面 f1(L = c1,R = c2;图 2.2 里的那个面)。两侧的原始变量、它们的前向导数,以及这个面的反向语句加给它们的伴随份额 :
The interior face f1 (L = c1, R = c2; the face of Figure 2.2). The two sides' primitives, their tangents, and the shares of their adjoints this face's reverse statements add, :
| 分量 | component | ||||||
|---|---|---|---|---|---|---|---|
| ρ | 0.901 | 0.9196 | −0.05611 | −0.1066 | 5.398 | 4.446 | |
| u | 0.1051 | 0.3029 | −0.1003 | −0.05589 | −5.019 | 5.663 | |
| v | 0.009038 | 0.08488 | 0.03651 | 0.1409 | 3.478 | −2.175 | |
| T | 1.078 | 1.06 | 0.08523 | 0.08442 | 4.114 | 5.151 | |
| ν̃ | 0.005251 | 0.00878 | −4.684×10−4 | −0.001949 | −0.001275 | 0.005119 |
面上的通量,它的前向导数(Roe 部分与粘性部分)与种子 :
The face's flux, its tangent (the Roe part and the viscous part), and the seed :
| 分量 | component | Φ | ||||
|---|---|---|---|---|---|---|
| ρ | −0.06187 | 0.0793 | 0 | 0.0793 | 24.79 | |
| ρu | −0.407 | 0.02742 | −9.332×10−4 | 0.02649 | −27.72 | |
| ρv | 0.321 | −3.615×10−5 | −0.003463 | −0.003499 | −5.261 | |
| ρE | −0.2339 | 0.2812 | 5.611×10−5 | 0.2813 | −3.844 | |
| ρν̃ | −5.233×10−4 | 6.296×10−4 | 4.870×10−5 | 6.783×10−4 | −0.03812 |
这个面上的局部对偶恒等式:两边都是 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).
壁面面 f33(L = c1)。壁面状态 ρw = 0.8968、Tw = 1.075,pw = 0.9642。通量只有动量与 ρν̃ 两处不为零;种子是 (边界面没有 R 侧):
The wall face f33 (L = c1). The wall state has ρw = 0.8968 and Tw = 1.075, pw = 0.9642. Only the momentum and ρν̃ entries of the flux are non-zero; the seed is (a boundary face has no R side):
| 分量 | component | Φ | 原始变量 | primitive | ||||
|---|---|---|---|---|---|---|---|---|
| ρ | 0 | 0 | 3.32 | ρ | −0.05611 | 11.03 | ||
| ρu | −0.4886 | −0.008852 | −17.6 | u | −0.1003 | −1.2 | ||
| ρv | −0.1808 | −2.326×10−4 | −6.429 | v | 0.03651 | −0.3701 | ||
| ρE | 0 | 0 | −0.05851 | T | 0.08523 | 9.108 | ||
| ρν̃ | 4.304×10−4 | −1.726×10−5 | −0.01063 | ν̃ | −4.684×10−4 | −0.001302 |
来流面 f45(面点方位 202°,两种处理各在自己的收敛解上)。本页自己的解用原来的处理,“原来的处理”一栏就是本页的伴随;另一栏取自另一页(伴随一致的版本)的解。对流部分的伴随落在面状态 Wf 的哪些分量上,以及牵引力的权重 的大小:
The inflow face f45 (its face point at 202°, each treatment at its own converged solution). This page's own solution uses the original treatment, so the “original” column is this page's own adjoint; the other column comes from the solution of the adjoint-consistent version. Where the convective part's adjoint lands on the face state Wf, and the size of the traction's weight :
| Wf 的分量 | component of Wf | 原来的处理 | original | 伴随一致 | adjoint-consistent |
|---|---|---|---|---|---|
| ρ | −9.365 | 0 | |||
| u | 7.933 | 0 | |||
| v | 3.375 | 0 | |||
| T | 132.3 | 15.2 | |||
| ν̃ | −0.001326 | 0 | |||
| |牵引力的权重| | |traction weight| | 8.296 | 6.994 |
原来的处理五个分量都有伴随(Roe 耗散读面状态的全部分量);伴随一致的处理只有 T。牵引力的权重在两种处理里都不为零:格心格式没有被替换的行,没有哪一句把这个组合在来流面上直接置零;附录 B.4 说明粘性两点差分的转置把它推向零,而这里的 ψ 取在单元中心。
The original treatment has an adjoint in all five components (Roe's dissipation reads every component of the face state); the adjoint-consistent one only in T. The traction's weight is non-zero in both: the cell scheme replaces no row, and no statement sets this combination to zero on the inflow face; Appendix B.4 explains how the transpose of the viscous two-point difference drives it towards zero, and ψ here is taken at the cell centres.
核对:上面的前向与伴随值由 kernels_ad.js 的语句算出;用 core.js 面核的局部磁带另算一遍(Jf 乘输入的点、JfT 乘 ),两者最大相对差 5.5×10−16;内部面上对偶恒等式两边相差 6.3×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 5.5×10−16 (relative); the two sides of the duality identity on the interior face differ by 6.3×10−17 (relative to the sum of the products' sizes) (computed by this page's code at build time).
图 9.7 把伴随的各遍放到网格上倒着执行,种子取第 11 节的伴随解,。面倒着一个接一个,每个面把 累加到两侧;每个控制体上画的是它五个分量 的累加值, 就是 SA 变量的伴随。梯度的权重经 ΓT 回到模板,最后经 ΠT 得到 :伴随方程在每个控制体上成立,精确到求解停下时的残差:判据(残差的 RMS 小于 10−13)在第 649 次迭代首次满足,本页用的是最后一步(第 811 次)迭代,它的 RMS 是 1.7×10−13,单个分量的残差最大 1.4×10−12(首次满足之后又迭代了 162 步,残差在这个量级上起伏,没有再降),所以扫描在每个控制体上留下的就是那里的 −g,差不超过这个残差;g 只在目标读到的 16 个控制体上不为零(共 24 个),其余 8 个控制体上扫描留下的只是这个残差,最大 1.4×10−12。
Figure 9.7 runs the adjoint's passes backwards on the mesh, with Section 11's adjoint as the seed, . The faces go one after another in reverse, each accumulating into its two sides; every control volume shows the accumulated values of its five components , and is the adjoint of the SA variable. The gradients' weights go back to their stencils through ΓT, and finally ΠT gives : 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 649, the page uses the last iterate (iteration 811), whose RMS residual is 1.7×10−13 with a largest single entry of 1.4×10−12 (after first meeting it the solve ran 162 more iterations, and the residual fluctuates at this level without falling further), so what the sweep leaves in each control volume is its −g to within that residual; g is non-zero only in the 16 control volumes the objective reads (of 24), and in the other 8 the sweep leaves only that residual, at most 1.4×10−12.
前向求解:A v = −f
The forward solve: A v = −f
前向方程用原始迭代的同一个 K 求解:
The tangent equation is solved with the same K as the primal iteration:
K 是 U* 处的两次对称 Gauss–Seidel(CFL 固定在 200),A v 是第 8 节的 residual_d 取 U_d = v。原始迭代在接近 U* 时的误差也按 I − KA 传播,所以两者的渐近速率相同,都是迭代矩阵 I − KA 的谱半径:二阶格式 ρ(I − KA) = 0.951(把 I − KA 装配成 120 × 120 的稠密矩阵,取它全部特征值的最大模;最大的两个是一对共轭复数 0.807 ± 0.503i,残差因此带着振荡衰减)。在残差从初值的 10−4 降到 10−11 的区间里拟合的每步因子是:原始 0.951、前向 0.951,与 ρ(I − KA) 的相对差 +0.0017%、
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.951 for the second-order scheme (the largest modulus among all the eigenvalues of the dense 120 × 120 matrix I − KA; the largest two are the complex pair 0.807 ± 0.503i, so the residual decays with an oscillation). Fitted over the band where each residual falls from 10−4 to 10−11 of its start, the factors per iteration are 0.951 (primal) and 0.951 (tangent), +0.0017% and +0.0023% 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.
结果:二阶格式 dCD/dα = 0.01979774、dCD/dM = −12.654212、dCD/dμref = 178.90741。它们与第 11 节伴随给出的值相对差 1.7×10−13(除以 |∂CD/∂D|、|ψTf| 与 |dCD/dD| 中最大的一个,见下);直接除以导数本身是 6.7×10−12。
The result: for the second-order scheme dCD/dα = 0.01979774, dCD/dM = −12.654212, dCD/dμref = 178.90741. They differ from the adjoint's values of Section 11 by a relative 1.7×10−13 (over the largest of |∂CD/∂D|, |ψTf| and |dCD/dD|, see below); over the derivative itself the difference is 6.7×10−12.
本页比较流动参数的导数时,相对差默认除以三个量中最大的一个:显式部分 |∂CD/∂D|、伴随部分 |ψTf|(等于前向的 |gTv|)与导数本身 |dCD/dD|。本页 dCD/dα = ∂CD/∂α + ψTf = −0.757 + 0.777 = 0.0198:两部分几乎抵消,和只有较大部分的 1/39。舍入误差随两部分的大小走,不随它们的和走,所以除以和会把它放大约 39 倍;按两部分归一量的是舍入误差真正所在的量级。第 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/dα = ∂CD/∂α + ψTf = −0.757 + 0.777 = 0.0198: the two parts nearly cancel, and the sum is 1/39 of the larger part. Round-off scales with the parts, not with their sum, so dividing by the sum inflates it about 39 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).
伴随求解:ATψ = −g
The adjoint solve: ATψ = −g
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
因为 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
这正是在 PT 上做两次同样的对称扫描(扫描次数更多时同理:k 次扫描是 Σj<k(I − K1P)jK1,它的转置是 PT 上的同一个和)。代码里 precond(P, b, 2, transposed) 正是这样:transposed 时每个对角块与邻居块都取转置,扫描顺序不变。二阶格式随机向量上 ⟨a, Kb⟩ 与 ⟨KTa, b⟩ 的相对差 7.9×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 7.9×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,
下面的动画逐行执行一次 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.
二阶格式的实测:两者在所有迭代上的最大相对差 4.6×10−13(按第 10 节的归一;除以导数本身是 1.8×10−11)。伴随在第 649 次迭代满足判据,同一区间拟合的每步因子 0.952(与 ρ(I − KA) 相差 +0.021%)。三个迭代(原始、前向、伴随)的渐近速率都是 ρ(I − KA) = 0.951:伴随的迭代矩阵 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 4.6×10−13 (in the normalisation of Section 10; over the derivative itself 1.8×10−11). The adjoint meets its criterion at iteration 649, with a fitted factor of 0.952 over the same band (+0.021% from ρ(I − KA)). The three iterations (primal, tangent, adjoint) share the asymptotic rate ρ(I − KA) = 0.951: 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.
ψ 的每个分量是对应方程残差的灵敏度:把某个控制体某个方程的残差加上一个小量 ε(Rk → Rk + ε),CD 改变 ψkε。
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ε.
下面的动画把两个迭代放在一起:左边是原始的伪时间迭代从来流状态走向 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.4 里(上面的演示一次只看一个)。
The five components of the converged ψ are drawn side by side in Figure 11.4 (the demo above shows one at a time).
逐步推导:一次对称扫描为什么是 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″ = 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 = 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)相差 1.4×10−15;transposed 扫描得到的矩阵与 KT 相差 1.0×10−15;从随机的 x 做一次扫描,与 x + K1(b − Px) 相差 2.1×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 1.4×10−15; the matrix of the transposed sweeps and KT differ by 1.0×10−15; one sweep from a random x and x + K1(b − Px) differ by 2.1×10−15 (all relative to the largest entry) (computed by this page's code at build time).
几何导数:dCD/dX
Geometric derivatives: dCD/dX
坐标经几何量进入残差:面法向 n、面点 xf(重构沿 xf − xi 外推)、中心与连线 Δx、体积 V、最小二乘权重(依赖中心位置)、壁面距离(依赖中心与最近的壁面边)。ψT∂R/∂X 是固定 U* 时对残差的一次反向扫描:本页把几何那一遍也写在同一套运算上,录一条包括几何的磁带(25904 个节点),用 ψ 作种子()反向扫一次,得到 与三个流动参数的 ;同一条磁带以 再扫一次给出显式部分,两者之和就是全部 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 (25904 nodes) and sweeps it backwards once with ψ as the seed (), which gives and, for the three flow parameters, ; one more sweep of the same tape with 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.7×10−15、旋转 2.8×10−14、伸缩 6.8×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.7×10−15, rotation 2.8×10−14, scaling 6.8×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.
演示里每个箭头是移动一个节点时 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 级离散问题的精确导数,但离连续问题的导数可能很远。dCD/dα = 0.019798 是两部分几乎抵消的结果:显式部分 ∂CD/∂α = −0.757,伴随部分 ψTf = 0.777。附录 A 把格心格式加密到第 4 级:dCD/dα = −1.469,连续伴随给出 −1.426,与第 0 级的值符号相反。这不是导数算错了(第 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. dCD/dα = 0.019798 is what is left when two parts nearly cancel: the explicit part ∂CD/∂α = −0.757 and the adjoint part ψTf = 0.777. Appendix A refines the cell scheme to level 4: dCD/dα = −1.469, and the continuous adjoint gives −1.426, of the opposite sign to the level-0 value. 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:
第三步,两次反向扫描。第一次把残差与目标录在以 𝒢 为输入的磁带上,种子是 与 ,一次得到全部 ;第二次把几何那一遍录在以 X 为输入的磁带上,分别用每个 作种子,得到它的那一份。七份之和就是第 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 and , which gives every at once; the second tapes the geometric pass with X as the input and sweeps back with each 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 的例子。格心页的面法向 nf = (yb − ya, xa − xb) 对端点坐标是常数矩阵;单元体积按鞋带公式 V = ½Σk(xkyk+1 − xk+1yk),∂V/∂xk = ½(yk+1 − yk−1)、∂V/∂yk = ½(xk−1 − xk+1);最小二乘权重见第 3 节最小二乘梯度推导的第六步,壁面距离见第 2 节壁面距离推导的第三至第五步。
Step 4, some ∂𝒢/∂X. On the cell page a face normal nf = (yb − ya, xa − xb) has a constant derivative with respect to its end points; a cell's volume by the shoelace formula V = ½Σk(xkyk+1 − xk+1yk) has ∂V/∂xk = ½(yk+1 − yk−1) and ∂V/∂yk = ½(xk−1 − xk+1); 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.
核对:七份之和与第 12 节的 dCD/dX 相差 2.1×10−15(相对最大分量);‖dCD/dX‖ = 13.201(本页代码在构建时计算)。
Check: the seven shares sum to Section 12's dCD/dX to 2.1×10−15 (relative to the largest entry); ‖dCD/dX‖ = 13.201 (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。前向在这些语句上放种子 ,伴随在它们上面收集:
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 on these statements, and the adjoint collects on them:
与 是 的反向扫描在来流语句里收集到的来流数据的伴随,Σ 跑遍每一次 μ(T) 的求值;CL、
and are the adjoints of the inflow data that the reverse sweep with 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:
| 参数 | parameter | 内部面 | interior faces | 壁面面 | wall faces | 来流面 | inflow faces | SA 源项 | SA sources | ψTf | ∂CD/∂D | dCD/dD |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| α | 0 | 0 | 0.7772 | 0 | 0.7772 | −0.7574 | 0.0198 | |||||
| M | 0 | 0 | 49.65 | 0 | 49.65 | −62.3 | −12.65 | |||||
| μref | 29.03 | 2.542 | 31.8 | 0.09467 | 63.47 | 115.4 | 178.9 |
α 与 M 只进入读 u∞ 的语句:来流面;μref 进入内部面、壁面面、来流面、SA 源项。表中每一行的 ψTf 加上显式部分就是 dCD/dD。
α and M enter only the statements that read u∞: the inflow faces; μref enters the interior faces, the wall faces, the inflow faces and the SA sources. Each row's ψTf plus the explicit part is dCD/dD.
第三步,几何那一遍倒着执行。上一小节第三步的第一次反向扫描给出七个存储数组的伴随 ,第二次把它们沿几何那一遍的磁带送回节点坐标;这里把第二次扫描照 mesh.js geometry() 的语句逐句写出,它们是上一小节第四步那些导数的转置:
Step 3, the geometric pass backwards. The first reverse sweep of Step 3 of the previous subsection gives the adjoints 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:
面法向 n = (yb − ya, xa − xb) 与面点 xf = ½(Xa + Xb) 的伴随各是两句加减;单元中心是顶点的平均, 分给它的 k 个顶点。第三行末的 Δxij 是最小二乘模板里的连线(到邻居中心,贴壁单元还到壁面点),第四行的 Δx 是一个面两侧中心的连线。壁面距离那一句是第 2 节壁面距离推导第三步的转置:前向里 d 对三点的导数是 nw、
The adjoints of a face normal n = (yb − ya, xa − xb) and of a face point xf = ½(Xa + Xb) are two additions and subtractions each; a cell centre is the mean of its vertices, and shares it among its k vertices. The Δxij at the end of the third line is a least-squares stencil's line (to a neighbour's centre, or a wall cell's 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 back with these three coefficients.
核对:三个参数的 ψTf 按语句拆开后,各格之和与整条磁带给出的 ψT∂R/∂D、与 core.js 的参数列算出的 ψTf 相差 1.8×10−14(相对各格的绝对值之和);把几何那一遍的语句照写成程序倒着执行,得到的 dCD/dX 与第 12 节一条磁带给出的相差 2.3×10−15(相对最大分量)(本页代码在构建时计算)。
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.8×10−14 (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 2.3×10−15 (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 的乘积次数(每次迭代一次):共 24290 次;伴随只解一次 ATψ = −g,649 次,再加两次反向扫描(ψT∂R/∂D 与 ∂CD/∂D)。两种办法给出的 51 个导数最大相对差 1.7×10−13。
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): 24290 in all, while the adjoint solves ATψ = −g once, in 649, plus two reverse sweeps (ψT∂R/∂D and ∂CD/∂D). The 51 derivatives of the two routes differ by at most 1.7×10−13 (relative).
验证:与有限差分对照
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 的 x | x of node 1 |
|---|---|---|---|---|---|---|
| 10−2 | 3.8×10−4 | 1.5×10−2 | 2.0×10−4 | |||
| 10−3 | 3.8×10−6 | 1.5×10−4 | 2.0×10−6 | |||
| 10−4 | 3.9×10−8 | 1.5×10−6 | 5.0×10−8 | |||
| 10−5 | 2.4×10−8 | 9.6×10−7 | 2.8×10−7 | |||
| 10−6 | 6.5×10−7 | 2.6×10−5 | 6.1×10−6 | |||
| 10−7 | 5.6×10−6 | 2.2×10−4 | 1.3×10−4 | |||
| 10−8 | 1.2×10−4 | 4.7×10−3 | 1.6×10−3 |
截断误差按 ε² 下降,α 在 ε = 10−5、节点 1 的 x 在 ε = 10−4 处与舍入误差相遇:最好的差分与伴随的相对差,α 为 2.4×10−8(除以导数本身 9.6×10−7),节点 1 的 x 为 5.0×10−8。最低点的具体数值取决于重算解的舍入误差,换一台机器、换一个浏览器都会略有不同(下面的演示在本机重算)。差分只能验证到这个量级;更严格的核对由复数步长(第 14 节)给出。
The truncation error falls as ε² and meets the round-off at ε = 10−5 for α and ε = 10−4 for x of node 1: the best difference agrees with the adjoint to a relative 2.4×10−8 for α (9.6×10−7 over the derivative itself) and 5.0×10−8 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.
复数步长
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/ε 就是 vk。二阶格式前 40 次迭代上,Im CD/ε 与前向估计的最大相对差 9.3×10−13(按第 10 节的归一;除以导数本身 3.6×10−11)。收敛后复数步长与伴随的相对差:3 个流动参数 9.8×10−13(按第 10 节的归一;除以导数本身 3.9×10−11),48 个坐标(按范数:最大差除以最大导数)1.8×10−13。
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 9.3×10−13 (in the normalisation of Section 10; 3.6×10−11 over the derivative itself). Once converged, the complex step agrees with the adjoint to a relative 9.8×10−13 for the 3 flow parameters (in the normalisation of Section 10; 3.9×10−11 over the derivatives themselves), and to 1.8×10−13 for the 48 coordinates (normwise: the largest difference over the largest derivative).
精度阶:制造解检验
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 ν̃:
μ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:
| 余量 | margin | R | M |
|---|---|---|---|
| S̃ 的分支:±(B + c2Ω)/Ω(区域 / 中心) | the S̃ branch: ±(B + c2Ω)/Ω (domain / centres) | 0.790 / 0.792 | 1.312 / 1.349 |
| r 的截断:±(r0 − 10)/10(区域 / 中心) | the cap on r: ±(r0 − 10)/10 (domain / centres) | 0.710 / 0.710 | 0.823 / 0.864 |
| 涡量:min|ω| / max|ω|,同号 | vorticity: min|ω| / max|ω|, one sign | 0.759 ✓ | 0.759 ✓ |
| ρ / T 的范围 | the ranges of ρ / T | 0.922–1.080 / 0.994–1.060 | 0.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 由 sympy 对解析的通量逐项求导得到(mms_gen.py),从不调用离散残差。壁面距离 d 只以代数方式进入 S,所以 s 在每个控制体中心用格式自己的 di 求值;积分用格式自己的单点规则(与 SA 源项相同),xi 是单元顶点的平均点。sympy 的源项与本页代码的通量公式互相核对过:在任取的点上用四阶中心差分对 model.js 的通量求散度,两者在差分截断与舍入误差内一致(check_mms.js)。为了只检验内部离散,这一节把精确解加在所有边界上(core.js 的 mms 模式;本页其余各节的边界条件不变):每个边界面都取对精确解的通量:Roe 通量的右侧是面中点的精确状态,粘性通量取中心到面点的两点差(含热流,功用边界速度),与第 4 节的来流面同一写法;贴壁单元最小二乘模板里的壁面点取精确的 u、v、ν̃(ρ、T 仍只用邻居)。
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 vertex average of the cell. 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): every boundary face takes the flux against the exact solution: the Roe flux with the exact state at the face midpoint on its right, and the viscous flux of the two-point difference from the centre to the face point (heat flux included, the work of the boundary velocity), written like Section 4's inflow face; the wall point in a wall cell's least-squares stencil carries the exact u, v, ν̃ (ρ and T still use the neighbours only).
网格族与误差
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 | 格式 | scheme | p(ρ) | p(ρu) | p(ρv) | p(ρE) | p(ρν̃) | p(CD) |
|---|---|---|---|---|---|---|---|---|---|
| R | 格心一阶 | cell first order | 0.71 | 0.94 | 0.95 | 0.70 | 0.84 | 0.80 | |
| R | 格心二阶 | cell second order | 1.73 | 1.93 | 2.01 | 1.86 | 1.92 | (0.51) | |
| R | 格点一阶 | node first order | 0.86 | 0.87 | 0.89 | 0.82 | 0.84 | 1.02 | |
| R | 格点二阶 | node second order | 2.00 | 2.06 | 2.12 | 1.96 | 2.04 | 1.99 | |
| M | 格心一阶 | cell first order | 0.76 | 0.94 | 0.90 | 0.76 | 0.77 | 0.78 | |
| M | 格心二阶 | cell second order | 1.99 | 1.91 | 1.95 | 1.94 | 1.98 | 1.86 | |
| M | 格点一阶 | node first order | 0.69 | 0.89 | 0.91 | 0.69 | 0.70 | 0.72 | |
| M | 格点二阶 | node second order | 2.03 | 2.04 | 2.12 | 2.01 | 2.06 | 2.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 wall faces' momentum flux, 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.
展开:各级网格的 L2 误差(解 R)Expand: the L2 errors on every level (solution R)
| 格式 | scheme | 级 | level | N | ‖e(ρ)‖ | ‖e(ρu)‖ | ‖e(ρv)‖ | ‖e(ρE)‖ | ‖e(ρν̃)‖ | |CD − CD,e| |
|---|---|---|---|---|---|---|---|---|---|---|
| 格心一阶 | cell first order | 1 | 96 | 2.9×10−3 | 7.3×10−3 | 5.3×10−3 | 7.3×10−3 | 1.2×10−4 | 3.8×10−2 | |
| 格心一阶 | cell first order | 2 | 384 | 1.7×10−3 | 3.7×10−3 | 2.5×10−3 | 4.4×10−3 | 6.7×10−5 | 4.7×10−2 | |
| 格心一阶 | cell first order | 3 | 1536 | 1.0×10−3 | 1.9×10−3 | 1.2×10−3 | 2.7×10−3 | 4.0×10−5 | 3.2×10−2 | |
| 格心一阶 | cell first order | 4 | 6144 | 6.3×10−4 | 9.9×10−4 | 6.1×10−4 | 1.7×10−3 | 2.3×10−5 | 1.9×10−2 | |
| 格心一阶 | cell first order | 5 | 24576 | 3.8×10−4 | 5.2×10−4 | 3.2×10−4 | 1.0×10−3 | 1.3×10−5 | 1.1×10−2 | |
| 格心二阶 | cell second order | 1 | 96 | 5.4×10−4 | 8.4×10−4 | 7.1×10−4 | 1.6×10−3 | 2.2×10−5 | 5.8×10−3 | |
| 格心二阶 | cell second order | 2 | 384 | 1.3×10−4 | 2.0×10−4 | 1.7×10−4 | 3.7×10−4 | 7.2×10−6 | 1.4×10−3 | |
| 格心二阶 | cell second order | 3 | 1536 | 3.9×10−5 | 5.2×10−5 | 3.7×10−5 | 8.9×10−5 | 2.3×10−6 | 1.6×10−4 | |
| 格心二阶 | cell second order | 4 | 6144 | 1.2×10−5 | 1.4×10−5 | 8.6×10−6 | 2.3×10−5 | 6.5×10−7 | 4.3×10−5 | |
| 格心二阶 | cell second order | 5 | 24576 | 3.8×10−6 | 3.6×10−6 | 2.1×10−6 | 6.4×10−6 | 1.7×10−7 | 3.0×10−5 | |
| 格点一阶 | node first order | 1 | 80 | 5.0×10−3 | 8.9×10−3 | 9.4×10−3 | 1.3×10−2 | 2.0×10−4 | 3.2×10−1 | |
| 格点一阶 | node first order | 2 | 288 | 2.8×10−3 | 5.7×10−3 | 5.8×10−3 | 7.2×10−3 | 1.6×10−4 | 1.3×10−1 | |
| 格点一阶 | node first order | 3 | 1088 | 1.6×10−3 | 3.4×10−3 | 3.4×10−3 | 4.0×10−3 | 1.1×10−4 | 5.5×10−2 | |
| 格点一阶 | node first order | 4 | 4224 | 8.5×10−4 | 2.0×10−3 | 1.9×10−3 | 2.3×10−3 | 6.4×10−5 | 2.5×10−2 | |
| 格点一阶 | node first order | 5 | 16640 | 4.7×10−4 | 1.1×10−3 | 1.0×10−3 | 1.3×10−3 | 3.6×10−5 | 1.3×10−2 | |
| 格点二阶 | node second order | 1 | 80 | 1.7×10−3 | 2.6×10−3 | 1.7×10−3 | 2.9×10−3 | 5.3×10−5 | 1.9×10−1 | |
| 格点二阶 | node second order | 2 | 288 | 4.8×10−4 | 6.8×10−4 | 4.1×10−4 | 1.0×10−3 | 1.4×10−5 | 5.5×10−2 | |
| 格点二阶 | node second order | 3 | 1088 | 1.3×10−4 | 1.7×10−4 | 9.9×10−5 | 2.9×10−4 | 3.6×10−6 | 1.5×10−2 | |
| 格点二阶 | node second order | 4 | 4224 | 3.2×10−5 | 4.0×10−5 | 2.3×10−5 | 7.9×10−5 | 8.5×10−7 | 3.8×10−3 | |
| 格点二阶 | node second order | 5 | 16640 | 7.9×10−6 | 9.5×10−6 | 5.3×10−6 | 2.0×10−5 | 2.1×10−7 | 9.6×10−4 |
展开:各级网格的 L2 误差(解 M)Expand: the L2 errors on every level (solution M)
| 格式 | scheme | 级 | level | N | ‖e(ρ)‖ | ‖e(ρu)‖ | ‖e(ρv)‖ | ‖e(ρE)‖ | ‖e(ρν̃)‖ | |CD − CD,e| |
|---|---|---|---|---|---|---|---|---|---|---|
| 格心一阶 | cell first order | 1 | 96 | 4.2×10−3 | 5.7×10−3 | 3.4×10−3 | 1.1×10−2 | 4.8×10−4 | 3.0×10−1 | |
| 格心一阶 | cell first order | 2 | 384 | 3.0×10−3 | 2.8×10−3 | 1.6×10−3 | 7.8×10−3 | 3.5×10−4 | 2.3×10−1 | |
| 格心一阶 | cell first order | 3 | 1536 | 1.9×10−3 | 1.4×10−3 | 8.2×10−4 | 5.0×10−3 | 2.2×10−4 | 1.5×10−1 | |
| 格心一阶 | cell first order | 4 | 6144 | 1.2×10−3 | 7.5×10−4 | 4.4×10−4 | 3.0×10−3 | 1.4×10−4 | 9.4×10−2 | |
| 格心一阶 | cell first order | 5 | 24576 | 6.9×10−4 | 3.9×10−4 | 2.4×10−4 | 1.8×10−3 | 8.0×10−5 | 5.5×10−2 | |
| 格心二阶 | cell second order | 1 | 96 | 7.2×10−4 | 5.9×10−4 | 4.9×10−4 | 1.8×10−3 | 1.8×10−4 | 3.6×10−2 | |
| 格心二阶 | cell second order | 2 | 384 | 2.4×10−4 | 1.5×10−4 | 1.2×10−4 | 5.1×10−4 | 4.9×10−5 | 1.4×10−2 | |
| 格心二阶 | cell second order | 3 | 1536 | 7.2×10−5 | 3.9×10−5 | 2.6×10−5 | 1.5×10−4 | 1.3×10−5 | 4.7×10−3 | |
| 格心二阶 | cell second order | 4 | 6144 | 2.0×10−5 | 1.0×10−5 | 6.2×10−6 | 4.1×10−5 | 3.4×10−6 | 1.4×10−3 | |
| 格心二阶 | cell second order | 5 | 24576 | 5.0×10−6 | 2.8×10−6 | 1.6×10−6 | 1.1×10−5 | 8.6×10−7 | 3.8×10−4 | |
| 格点一阶 | node first order | 1 | 80 | 5.6×10−3 | 6.7×10−3 | 6.5×10−3 | 1.5×10−2 | 6.5×10−4 | 4.5×10−1 | |
| 格点一阶 | node first order | 2 | 288 | 3.5×10−3 | 4.0×10−3 | 3.7×10−3 | 9.4×10−3 | 4.2×10−4 | 2.6×10−1 | |
| 格点一阶 | node first order | 3 | 1088 | 2.1×10−3 | 2.3×10−3 | 2.1×10−3 | 5.8×10−3 | 2.7×10−4 | 1.6×10−1 | |
| 格点一阶 | node first order | 4 | 4224 | 1.3×10−3 | 1.3×10−3 | 1.1×10−3 | 3.6×10−3 | 1.6×10−4 | 9.9×10−2 | |
| 格点一阶 | node first order | 5 | 16640 | 8.3×10−4 | 6.8×10−4 | 6.0×10−4 | 2.2×10−3 | 1.0×10−4 | 6.0×10−2 | |
| 格点二阶 | node second order | 1 | 80 | 1.9×10−3 | 1.6×10−3 | 1.1×10−3 | 4.1×10−3 | 1.8×10−4 | 2.8×10−1 | |
| 格点二阶 | node second order | 2 | 288 | 6.0×10−4 | 4.1×10−4 | 2.5×10−4 | 1.4×10−3 | 6.1×10−5 | 8.4×10−2 | |
| 格点二阶 | node second order | 3 | 1088 | 1.7×10−4 | 1.0×10−4 | 5.7×10−5 | 4.2×10−4 | 1.7×10−5 | 2.3×10−2 | |
| 格点二阶 | node second order | 4 | 4224 | 4.3×10−5 | 2.4×10−5 | 1.3×10−5 | 1.1×10−4 | 4.4×10−6 | 5.9×10−3 | |
| 格点二阶 | node second order | 5 | 16640 | 1.1×10−5 | 5.9×10−6 | 3.0×10−6 | 2.7×10−5 | 1.1×10−6 | 1.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、 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 cell scheme's wall shear stress uses the cell gradient and the two-point difference from the centre to the face point, only O(h) accurate on a single face; this page's scheme measures drag orders of 1.86 (solution M), above 1, so on solution M this O(h) part is not yet the main part of the drag error.−1.6×10−4、4.3×10−5、3.0×10−5,在第 3、4 级之间变号。变号说明误差里至少有两部分符号相反、随 h 减小的快慢不同;变号的那一段没有阶,紧接着的一段里两部分仍在相消,观测阶也不代表收敛速率。最后两级的观测阶(不计受变号影响的)在 1.86–2.03 之间。格心格式在壁面上的剪应力用单元梯度与中心到面点的两点差,单个面上只有 O(h) 精度;本页格式测得的阻力阶为 1.86(解 M),高于 1,说明在解 M 上这一 O(h) 部分还不是阻力误差的主要部分。 - 对伴随的意义:第 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.
伴随方程的三种解法: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.951,要 649 步才满足判据。这一节在同一个系统 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.951, and the criterion takes 649 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 4, the storage by 16 and the work by 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 order | GS | GMRES | LU |
|---|---|---|---|---|
| 迭代步数(AT 乘积) | iterations (products with AT) | 649 | 72 (76) | — (120) |
| 最终残差 ‖ATψ + g‖(均方根) | final residual ‖ATψ + g‖ (rms) | 1.7×10−13 | 6.4×10−14 | 6.0×10−14 |
| 导数与 GS 的最大相对差 | largest relative difference of the derivatives from GS | — | 6.1×10−14 (2.4×10−12) | 2.6×10−13 (1.0×10−11) |
| 一阶格式:迭代步数 | first order: iterations | 48 | 21 | — |
三种解法给出的导数在舍入误差内相同。GMRES 的步数少得多(72 对 649),因为它不只沿最新的方向走,而是在所有已产生的方向里挑最好的组合:GS 迭代里衰减得慢、接近 ρ(I − KA) 的那几个误差分量,GMRES 几步就能把它们一起消掉。它的代价是每步的正交化与 30 个基向量的存储。LU 的装配本身就要 120 次 residual_d,比 GMRES 的 76 次乘积多,外加 O(n³) 的分解;它的用处是给迭代解法一个不依赖迭代的参照。
The three solvers give the same derivatives to round-off. GMRES needs far fewer steps (72 against 649): 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 76 products, plus the O(n³) factorisation; its use is a reference for the iterative solvers that involves no iteration at all.
上面演示里的播放器把 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 ψ.
总结
Summary
| 做什么 | what | 怎样做 | how | |
|---|---|---|---|---|
residual(U) | R(U) | R(U) | 几遍循环:π、Γ、面、源项 | passes: π, Γ, faces, source |
residual_d(U, U_d) | 同样的几遍、同样的顺序,核换成局部 Jacobian | the same passes in the same order, kernels replaced by local Jacobians | ||
residual_b(U, R_b) | 几遍倒序,每遍转置 | the passes reversed, each transposed | ||
solve | R(U) = 0 | R(U) = 0 | 伪时间 + 两次对称块 GS(P = 一阶 Roe + 薄剪切层) | pseudo-time + two symmetric block GS sweeps (P = first-order Roe + thin shear layer) |
tangent | A v = −f | A v = −f | 同一个 K,每个设计变量一次 | the same K, once per design variable |
adjoint | ATψ = −g | ATψ = −g | KT = PT 上的同一个 SGS,一次得到全部导数 | KT = the same SGS on PT, all derivatives at once |
complex step | Im 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.73–2.01,一阶 0.70–0.95 | Section 15: two manufactured solutions, levels 1–5; this page's scheme p = 1.73–2.01 at second order, 0.70–0.95 at first |
GMRES, LU | ATψ = −g | ATψ = −g | 第 16 节:同一个方程、同一组导数;GMRES 72 步,GS 649 步 | Section 16: the same equation, the same derivatives; GMRES in 72 steps, GS in 649 |
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.8×10−13(按第 10 节的归一;除以导数本身 3.9×10−11),48 个坐标(按范数)1.8×10−13。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.8×10−13 for the flow parameters (in the normalisation of Section 10; 3.9×10−11 over the derivatives themselves), and by 1.8×10−13 (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.
附录 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.
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 λ = (λρ, β, ζ, φ):
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
(𝒮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)
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:
修正的涡量 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,
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),
于是净源项 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
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:
所有系数都取在原始解所在的分支上: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:
其中 𝒜 = λρ + β·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:
在来流上 φ = 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:
| 级 | level | h | λρ | β1 | β2 | ζ | φ |
|---|---|---|---|---|---|---|---|
| 2 | 0.1909 | 7.5×10−3 | 3.5×10−3 | 3.4×10−3 | 2.4×10−3 | 8.9×10−4 | |
| 3 | 0.0955 | 1.5×10−3 | 9.3×10−4 | 8.4×10−4 | 4.3×10−4 | 2.0×10−4 | |
| 4 | 0.0477 | 3.3×10−4 | 2.3×10−4 | 2.1×10−4 | 8.4×10−5 | 4.8×10−5 | |
| 5 | 0.0239 | 7.9×10−5 | 5.8×10−5 | 5.2×10−5 | 1.8×10−5 | 1.2×10−5 | |
| 阶 | order | 2.06 | 2.00 | 2.00 | 2.20 | 2.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 | 格点 CD | node CD | 格心 CD | cell CD |
|---|---|---|---|---|---|
| 0 | 54.2003 | 6.2300 | |||
| 1 | 11.4286 | 6.6549 | |||
| 2 | 7.2720 | 6.6499 | |||
| 3 | 6.5935 | 6.6457 | |||
| 4 | 6.4399 | 6.5991 |
| 级 | level | 连续伴随 dCD/dα | continuous dCD/dα | 格点离散伴随 | node discrete | 格心离散伴随 | cell discrete |
|---|---|---|---|---|---|---|---|
| 0 | — | −15.5780 | 0.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/dM | continuous dCD/dM | 格点离散伴随 | node discrete | 格心离散伴随 | cell discrete |
|---|---|---|---|---|---|---|---|
| 0 | — | −45.1009 | −12.6542 | ||||
| 1 | 30.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μref | continuous dCD/dμref | 格点离散伴随 | node discrete | 格心离散伴随 | cell discrete |
|---|---|---|---|---|---|---|---|
| 0 | — | 620.99 | 178.91 | ||||
| 1 | 327.78 | 290.68 | 207.50 | ||||
| 2 | 252.50 | 236.37 | 218.43 | ||||
| 3 | 227.39 | 221.99 | 221.95 | ||||
| 4 | 220.92 | 218.27 | 220.58 |
连续伴随与本页(格心)离散伴随给出的导数的相对差(除以格心值,第 1、2、3、4 级):α −208.6% → −24.1% → −0.4% → 2.9%;M 326.1% → 50.3% → 8.0% → 0.9%;μref 58.0% → 15.6% → 2.4% → 0.2%。相邻两级之比:M 0.15、0.16、0.11;μref 0.27、0.16、0.06;α 的差在第 3、4 级之间变号(两者交叉),比值没有意义。从第 1 级到第 4 级,三个差分别缩小到原来的 1/71、1/377、1/383,但相邻两级之比没有稳定在 h2 的 1/4;M、μref 的最后一步最快。第 4 级:格点离散伴随给出 −1.389、
The relative difference between the derivatives from the continuous adjoint and from this page's (cell) discrete adjoint (over the cell value, levels 1, 2, 3, 4): α −208.6% → −24.1% → −0.4% → 2.9%; M 326.1% → 50.3% → 8.0% → 0.9%; μref 58.0% → 15.6% → 2.4% → 0.2%. The ratios between neighbouring levels: M 0.15, 0.16, 0.11; μref 0.27, 0.16, 0.06; for α the difference changes sign between levels 3 and 4 (the two cross), and a ratio means nothing there. From level 1 to level 4 the three differences shrink by factors of 71, 377, 383, but the ratio between neighbouring levels does not settle at a quarter (h2); for M, μref the last step is the fastest. On level 4 the node scheme's discrete adjoint gives −1.389, −12.763, 218.3, this page's (cell) −1.469, −11.941, 220.6. 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). 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 (this cell page's ratios are mostly even below a quarter: its comparison carries the difference between the two schemes' primal solutions, and the two errors partly cancel). 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)。连续伴随在单元中心取 P1 插值,每个单元都参加比较。离来流边界 0.8 以外的单元上,两者的相对均方根差:
The adjoint fields themselves. Row i of the cell scheme's residual is the integral of the conservative residual over cell i, 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 continuous adjoint is its P1 interpolant at the cell centres, and every cell takes part. Over the cells farther than 0.8 from the inflow, the relative RMS difference of the two:
| 级 | level | ψρ ↔ λρ − ν̃φ/ρ | ψρu ↔ β1 | ψρv ↔ β2 | ψρE ↔ ζ | ψρν̃ ↔ φ/ρ |
|---|---|---|---|---|---|---|
| 2 | 96.4% | 23.4% | 24.8% | 30.0% | 36.2% | |
| 3 | 22.6% | 9.4% | 10.9% | 10.2% | 15.1% | |
| 4 | 16.9% | 4.4% | 7.8% | 9.3% | 5.7% |
动量与 ν̃ 的乘子逐级靠近(第 3→4 级之比 0.38–0.71);质量与能量的乘子收敛得慢一些,它们与来流边界层和出口的 𝒜 = 0 耦合在一起。靠近来流,连续伴随有 A.3 所说的边界层(ζ 与 λρ 向来流陡升;附录 B.6 的线性化给出它在正面的厚度约 0.15–0.16)。本页的格心离散伴随在那里也有这一层,但强得多:离来流最近的单元上 ψρ 是 λ 对应值的 3.1 倍。原因在来流面的 Roe 通量:它对虚拟状态的耗散依赖单元的 ρ、u、ν̃,转置后给离散伴随多出一个连续伴随在来流上没有的边界关系(附录 B.3),这就是伴随不一致。来流 0.3 以内 ψρ 的相对均方根差是 204% → 273% → 251%,加密后仍高于第 2 级的值。离散导数仍是离散问题的精确导数;但来流附近的 ψ 不能当作 λ 的近似来用。
The multipliers of momentum and ν̃ approach each other level by level (a ratio of 0.38–0.71 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 cell discrete adjoint carries this layer too, but much too strong: in the cell nearest the inflow ψρ is 3.1 times λ's value. The cause is the inflow face's Roe flux: its dissipation against the ghost state reads the cell's ρ, u and ν̃, and its transpose adds a boundary relation the continuous adjoint does not have at the inflow (Appendix B.3): adjoint inconsistency. Within 0.3 of the inflow the relative RMS difference of ψρ is 204% → 273% → 251%, still above its level-2 value under refinement. The discrete derivatives are still the exact derivatives of the discrete problem; but near the inflow ψ cannot be used as an approximation of λ.
结论:离散伴随在每一级都是离散问题的精确导数(第 13、14 节);连续伴随是对连续问题导数的另一种近似。从第 1 级到第 4 级,两者的差缩小到原来的 1/71、1/377、1/383(α、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 71, 377, 383 (α, 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).
附录 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. The cell scheme has no replaced rows, so one rule does it:
- 边界通量依赖的状态分量。边界面的通量 Fbc 读哪些状态分量,AT 在这些分量的列上就多出 (∂Fbc/∂U)Tψ。连续问题在来流上的通量只经温度 T 和牵引力、SA 扩散通量这些自由的量依赖解:ρ、u、ν̃ 是给定值。离散通量若还依赖单元的 ρ、u 或 ν̃,转置后就多出连续伴随没有的边界项。The state components a boundary flux reads. Whatever state components the boundary 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 cell'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 ↔ ζ, ψρν̃ ↔ φ/ρ.
B.3 原来的来流处理为什么伴随不一致
B.3 Why the original inflow treatment is adjoint-inconsistent
格心格式原来在来流面上取 Roe 通量对虚拟状态 Wg = (ρ∞, u∞, v∞, Tf, ν̃∞):
The cell scheme originally took, on an inflow face, the Roe flux against the ghost state Wg = (ρ∞, u∞, v∞, Tf, ν̃∞):
面状态 Wf 是单元自己的重构,所以 Fbc 依赖单元状态的全部五个分量,不只是 T:质量通量里有 ½ρfuf·n,熵波与声波的耗散也随单元的 ρ、u 变。按 B.2 的规则,来流单元的质量、动量与 ν̃ 列上多出边界项;质量列上的那一项给 λρ 加了一个连续伴随没有的边界关系,正是在伴随的出口多给了条件。耗散项对单元状态的导数的主部是 ½|J̃c||n|,大小只随面积变,所以这一项加密也不会消失。
The face state Wf is the cell's own reconstruction, so Fbc depends on all five components of the cell state, not on T alone: the mass flux holds ½ρfuf·n, and the dissipation of the entropy and acoustic waves moves with the cell's ρ and u as well. By the rule of B.2 the mass, momentum and ν̃ columns of an inflow cell receive boundary terms; the one in the mass column gives λρ a boundary relation the continuous adjoint does not have: a condition too many at the adjoint's outlet. The leading part of the dissipation's derivative with respect to the cell state is ½|J̃c||n|, which changes with the face area only, so refinement does not remove this term.
原始解同样受影响,而且在本页的网格上并不小。两个侧面上贴边界那一排带来流面的单元,原处理的 ρ 最低 0.967、0.965、0.967,一致的版本 0.920、0.911、0.909(第 2、3、4 级),加密都不收敛到同一个值;第 4 级的阻力 6.5991 与 6.4138 相差 2.9%,而格点格式的两种处理只差 0.25%(6.4399 与 6.4560)。按理,耗散项正比于面状态与虚拟状态之差,面状态若趋于边界上的状态,它也会趋于零;但来流边界上有一层厚约 0.002–0.007 的粘性子层(B.6),而第 4 级网格在来流边界上的网格尺寸约 0.045,分辨不了它,所以在本页的网格上看不到这个极限。
The primal solution is affected too, and on this page's meshes not by little. On the two side faces, the row of cells with an inflow face drops to ρ = 0.967, 0.965, 0.967 in the original and 0.920, 0.911, 0.909 in the consistent version (levels 2, 3, 4), and refinement does not bring them together; on level 4 the drag is 6.5991 against 6.4138, 2.9% apart, while the node scheme's two treatments differ by only 0.25% (6.4399 and 6.4560). In principle the dissipation is proportional to the difference between the face state and the ghost state and would go to zero if the face state approached the state on the boundary; but the inflow boundary carries a viscous sublayer about 0.002–0.007 thick (B.6), and on level 4 the mesh size at the inflow boundary is about 0.045, which cannot resolve it, so this limit is not reached on this page's meshes.
B.4 伴随一致的来流处理
B.4 The adjoint-consistent inflow treatment
一致的版本只换对流通量:来流面上取边界状态 Wbc = (ρ∞, u∞, v∞, Tf, ν̃∞) 的物理通量 F(Wbc)·n。它只经 Tf 依赖单元,按 B.2 的规则只有温度方向上有边界项;质量通量是给定值,λρ 不受约束。这与 Hartmann(2007)对间断 Galerkin 格式得出的要求相同:边界上用边界状态的物理通量,而不是数值通量。粘性部分不变:面点上 u、ν̃ 取来流值的两点差分,它的转置在同一个面上把 ψρu + u∞ψρE 与 ψρν̃ 推向零,即 β + ζu = 0 与 φ = 0;能量里的功 u∞·τn 与动量用同一个 τn,否则 β + ζu 这个组合凑不起来。温度方向上,动量里的压力 ρ∞Tfn 与能量里的 ρ∞cpTfun 在 β = −ζu 时合成 ρ∞cvunζ,面上没有热流,于是得到 Robin 条件。
The consistent version changes the convective flux only: an inflow face takes the physical flux F(Wbc)·n of the boundary state Wbc = (ρ∞, u∞, v∞, Tf, ν̃∞). It reads the cell through Tf alone, so by the rule of B.2 the only boundary term is in the temperature direction; the mass flux is given, and λρ is left free. This is the requirement Hartmann (2007) found for discontinuous Galerkin schemes: on the boundary, the physical flux of the boundary state rather than a numerical flux. The viscous part is unchanged: the two-point difference to u and ν̃ at the face point, whose transpose drives ψρu + u∞ψρE and ψρν̃ to zero on the same face, i.e. β + ζu = 0 and φ = 0; the work u∞·τn in the energy row uses the momentum's own τn, without which the combination β + ζu could not form. In the temperature direction the pressure ρ∞Tfn in the momentum and ρ∞cpTfun in the energy combine at β = −ζu into ρ∞cvunζ, and with no heat flux through the face this is the Robin condition.
图 B.1 把附录 B 的转置规则落到本页的一个来流面上:对流通量对面状态 Wf = (ρ, u, v, T, ν̃) 的 Jacobian 有哪些非零列,转置后的边界项就落在哪些方向。原来的处理有 5 列非零(ρ、u、v、T、ν̃),伴随一致的处理只有 1 列(T)。粘性部分两种处理相同,不在图里。
Figure B.1 applies Appendix B's transpose rule to one inflow face of this page: the non-zero columns of the convective flux's Jacobian with respect to the face state Wf = (ρ, 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). The viscous part is the same in both treatments and is not in the figure.
B.5 数值比较
B.5 The numbers
两种版本各自的连续伴随(系数取同一版本格点格式的解)与离散伴随逐级比较。下表是离来流边界 0.3 以内的单元上 ψ − λ 的相对均方根;离来流 0.8 以外两种版本相差无几(第 4 级:ψρ 17% 与 16%,ψρE 9% 与 7%)。
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 cells within 0.3 of the inflow boundary; beyond 0.8 from it the two versions are alike (level 4: ψρ 17% and 16%, ψρE 9% and 7%).
| 级 | level | 原处理 ψρ | original ψρ | 原处理 ψρE | original ψρE | 一致 ψρ | consistent ψρ | 一致 ψρE | consistent ψρE |
|---|---|---|---|---|---|---|---|---|---|
| 2 | 204% | 141% | 137% | 101% | |||||
| 3 | 273% | 178% | 155% | 103% | |||||
| 4 | 251% | 154% | 101% | 63% |
一致的版本到第 3→4 级开始下降(之比 ψρ 0.65、ψρE 0.61;ψρ 137%→155%→101%),原来的版本仍高于第 2 级的值(204%→273%→251%)。格心格式在来流附近误差大、下降也晚:两个侧面上来流几乎与边界平行,贴边界的那一排单元的解有偏差(B.6),而连续伴随在那里的层又最厚(约 0.31–0.47)。下图沿 180° 网格线看:一致版本的 ψ 跟着连续伴随的层走;原来的版本也有这一层,但离来流最近的单元上 ψρ 约为 λ 的 3.1 倍。
The consistent version starts to fall from level 3 to 4 (ratios 0.65 for ψρ and 0.61 for ψρE; ψρ 137%→155%→101%), while the original stays above its level-2 value (204%→273%→251%). The cell scheme's error next to the inflow is large and falls late: on the two side faces the inflow runs almost along the boundary and the row of cells along it carries a biased solution (B.6), where the continuous adjoint's layer is also thickest (about 0.31–0.47). The figure below looks along the 180° mesh line: the consistent ψ follows the continuous adjoint's layer; the original has the layer too, with ψρ about 3.1 times λ's value in the cell nearest the inflow.
导数本身在两种版本里都是精确的。第 4 级网格上两种版本的 CD、格心离散伴随给出的导数,以及同一版本连续伴随与它的相对差(除以离散值,与附录 A 相同):
The derivatives themselves are exact in both versions. On level 4, the two versions' CD, the derivatives from the cell discrete adjoint, and the same version's continuous adjoint's relative difference from them (over the discrete value, as in Appendix A):
| CD | dCD/dα | 与连续伴随之差 | vs continuous | dCD/dM | 与连续伴随之差 | vs continuous | dCD/dμref | 与连续伴随之差 | vs continuous | |
|---|---|---|---|---|---|---|---|---|---|---|
| 原处理(本页)original (this page) | 6.5991 | −1.4689 | 2.9% | −11.9406 | 0.9% | 220.6 | 0.2% | |||
| 一致consistent | 6.4138 | −1.3258 | 6.8% | −12.4496 | 2.7% | 214.6 | 2.7% |
伴随一致性管的是 ψ 在边界附近趋于什么,不直接决定导数误差的大小:导数误差还来自原始解本身、交界点与角点的奇性(附录 A.6)。格心格式上一致的版本的导数从更远处趋近连续伴随的导数(B.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 cell scheme the consistent version's derivatives approach the continuous adjoint's from further away (the side-face bias of B.6), shrinking level by level.
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。侧面上两种版本的原始解不同。格心格式上,贴边界的一排三角形(带来流面的与只以顶点碰到边界的相间)在一致的版本里密度交替:带来流面的单元 ρ 最低 0.920、0.911、0.909(第 2、3、4 级),加密不减;原处理的 Roe 耗散把它拉近 ρ∞(0.967、0.965、0.967)。正面上两者都在 1 的 0.6% 以内。这些单元的 ρ 只经质量通量 ρ∞u∞·n 与边界相连,|u∞·n| 小时这一联系弱,而贴边界单元的最小二乘梯度只有两个邻居。偏差集中在这一排:第 4 级上与格点解的 ρ 之差,带来流面的单元最大 0.056,同一排只以顶点碰到边界的单元 0.015,再往里(到 0.3)0.004。
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. On the cell scheme, the row of triangles along the boundary (those with an inflow face alternating with those that touch the boundary at a vertex only) carries an alternating density in the consistent version: the cells with an inflow face drop to ρ = 0.920, 0.911, 0.909 (levels 2, 3, 4), and refinement does not reduce it; the original's Roe dissipation pulls them toward ρ∞ (0.967, 0.965, 0.967). On the front both stay within 0.6% of 1. These cells' ρ is tied to the boundary only through the mass flux ρ∞u∞·n, a weak tie where |u∞·n| is small, and a boundary cell's least-squares gradient has only two neighbours. The bias sits in this row: on level 4 the ρ differs from the node solution's by at most 0.056 in the cells with an inflow face, 0.015 in the cells of the same row that touch the boundary at a vertex, and 0.004 further in (up to 0.3).
原因在连续问题里:把定常 Navier–Stokes 方程沿来流边界的法向线性化,亚声速来流上恰有一个离开边界衰减的粘性模态,厚度约 4μe|un|/(3p):本页的数值是侧面 0.0022–0.0034、正面 0.0066–0.0071。在这一层里 ρ 变化而 ρun 与 T 几乎不变;本页任何一级网格都分辨不了它(最细的网格第 4 级,贴来流边界的第一排节点离边界 0.045)。于是层外的解看到的边界条件取决于离散怎样跨过这一层:一致的版本只给跨层不变的质量通量;原处理的 Roe 通量还经熵波把面上的 ρ 拉向 ρ∞。同一个线性化的另一个模态朝区域内增长,厚度 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 consistent version gives only the mass flux, which does not change across the layer; the original's Roe flux also pulls the face's ρ toward ρ∞ through the entropy wave. 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.