OpenFOAM 中的梯度计算:高斯法
Contents
OpenFOAM 采用同位网格离散计算域,速度和压力等物理量均存储在有限控制体单元的体心。对于同位网格,高斯法是最常用的计算梯度的方法。
高斯定理可以将体积分转化为封闭曲面积分:
$$ \begin{equation} \int_V \nabla \cdot \mathbf F dV = \oint_S \mathbf n \cdot \mathbf F dS \end{equation} $$
其中,$\mathbf F$ 为任意矢量,$V$ 为空间体积,$S$ 为空间 $V$ 的表面,$\mathbf n$ 为 $dS$ 的单位法向量。
标量场的梯度
对于标量场 $T$,要计算其梯度 $\nabla T$,可以假设一任意常矢量 $\mathbf c$,有以下公式 $ \require{cancel} $:
$$ \begin{equation} \nabla \cdot (\mathbf c T) = \mathbf c \cdot \nabla T + \cancel{T \nabla \cdot \mathbf c} \end{equation} $$
对上式积分,有
$$ \begin{equation} \int_V \nabla \cdot (\mathbf c T) dV = \int_V \mathbf c \cdot \nabla T dV \label{eq:div_scalar} \end{equation} $$
对方程 $\eqref{eq:div_scalar}$ 左端项运用高斯定理,并将 $\mathbf c$ 移至积分外,可得
$$ \begin{equation} \int_V \nabla \cdot (\mathbf c T) dV = \oint_S \mathbf n \cdot (\mathbf c T) d S = \mathbf c \cdot \oint_S \mathbf n T d S \end{equation} $$
将方程 $\eqref{eq:div_scalar}$ 右端项中的 $ \mathbf c $ 移至积分外,有
$$ \begin{equation} \int_V \mathbf c \cdot \nabla T dV = \mathbf c \cdot \int_V \nabla T dV \end{equation} $$
于是有
$$ \begin{equation} \mathbf c \cdot \int_V \nabla T dV = \mathbf c \cdot \oint_S \mathbf n T d S \end{equation} $$
由于 $ \mathbf c $ 是任意常矢量,所以我们可以得到:
$$ \begin{equation} \boxed{\int_V \nabla T dV = \oint_S \mathbf n T d S = \oint_S d \mathbf S T} \end{equation} $$
可见对标量场梯度的体积分可以通过高斯定理转化为面积分。
矢量场的梯度
对于矢量场 $ \mathbf U $,其梯度可以表示为 $ \nabla \mathbf U $ 或 $ \nabla \otimes \mathbf U $。其中 $ \otimes $ 为张量积符号,其定义如下:
$$ \begin{equation} \mathbf a \otimes \mathbf b \equiv \mathbf a \cdot \mathbf b^T \end{equation} $$
于是 $ \nabla \otimes \mathbf U $ 可以表示为
$$ \begin{equation} \nabla \otimes \mathbf U = \nabla \cdot \mathbf U^T = (\nabla U_1 ; \nabla U_2 ; \nabla U_3) \end{equation} $$
对其积分,可得
$$ \begin{equation} \int_V \nabla \otimes \mathbf U dV = \int_V (\nabla U_1 ; \nabla U_2 ; \nabla U_3) dV = \oint_S (\mathbf n U_1 ; \mathbf n U_2 ; \mathbf n U_3) d S = \oint_S \mathbf n \otimes \mathbf U d S \end{equation} $$
化简后得到:
$$ \begin{equation} \boxed{\int_V \nabla \otimes \mathbf U dV = \oint_S \mathbf n \otimes \mathbf U d S = \oint_S d \mathbf S \otimes \mathbf U} \end{equation} $$
可见对矢量场梯度的体积分也可以通过高斯定理转化为面积分。
有限体积近似
上面我们得到了标量场和矢量场梯度的体积分,而有限体积法将连续的空间域划分成有限数量个控制体,如何进一步计算梯度在体心处的值?这里可以采用有限体积近似中的线性假设。
对于任意有限控制体 $ V $,其体心(形心) $ P $ 的定义满足:
$$ \begin{equation} \int_V (\mathbf x - \mathbf x_P) dV = 0 \end{equation} $$
假定场量 $ \phi $ 在控制体单元空间内线性变化,控制体内任意一点 $ \mathbf x $ 处的 $ \phi $,记为 $ \phi_\mathbf x$,满足
$$ \begin{equation} \phi_\mathbf x \approx \phi_P + (\nabla \phi)_P \cdot (\mathbf x - \mathbf x_P) \end{equation} $$
上式可以看作略去二阶及更高阶项的泰勒展开形式,因此具有二阶精度。
对控制体积分,可得
$$ \begin{equation} \int_V \phi_\mathbf x dV = \int_V \left[\phi_P + (\nabla \phi)_P \cdot (\mathbf x - \mathbf x_P)\right] dV = \phi_P V \end{equation} $$
上式表示在控制体内线性变化的物理量 $ \phi $ 对控制体积分等于体心的值 $ \phi_P $ 乘以控制体体积 $ V $,即
$$ \begin{equation} \phi_P = \frac{1}{V}\int_V \phi_\mathbf x dV \end{equation} $$
因此,标量 $ T $ 在体心处的梯度可以表示为:
$$ \begin{equation} (\nabla T)_ % workaround for hugo P = \frac{1}{V} \int_V (\nabla T) dV = \frac{1}{V} \oint_S d \mathbf S T = \frac{1}{V} \sum\limits_{face} \mathbf S_{face} T_{face} \end{equation} $$
同理,矢量 $ \mathbf U $ 在控制体体心处的梯度可以表示为:
$$ \begin{equation} (\nabla \otimes \mathbf U)_ % workaround for hugo P = \frac{1}{V} \sum\limits_{face} \mathbf S_{face} \otimes \mathbf U_{face} \end{equation} $$
OpenFOAM 的实现
注意到 $ T $ 和 $ \mathbf U $ 的梯度计算具有相同的形式,因此 OpenFOAM 采用操作符重载(operator overloading)和类模板(class template)实现泛型编程(generic programming),减少代码重复率。下面以 OpenFOAM 7 为例说明。
操作符重载
利用 operator *
实现标量与矢量相乘,可用于计算 $\mathbf S_{face} T_{face}$ :
|
|
利用 operator *
实现矢量与矢量相乘,可用于计算 $\mathbf S_{face} \otimes \mathbf U_{face}$:
|
|
类模板
通过 calcGrad
函数计算体心梯度:
|
|
这个函数的类模板参数 Type
可以是 scalar
或 vector
。通过 Foam::outerProduct<Foam::vector, Type>::type
得到梯度的类型。
- 若是
Type = scalar
,则其梯度类型为vector
; - 若是
Type = vector
,则其梯度类型为tensor
。
上面的代码调用了 gradf
函数,计算体心梯度的工作实际上由这个函数完成。在执行 gradf
函数前,已经通过 tinterpScheme_().interpolate(vsf)
将体心场插值计算面心场,将并面心场作为参数 ssf
传给 gradf
函数。然后 gradf
函数将面心值与面法向量相乘、求和,并除以控制体体积,得到体心梯度:
|
|
参考资料
Jasak, H. (2009). Finite Volume Discretisation with Polyhedral Cell Support.