创建 MAC 速度
为了在面上创建法向速度,我们首先使用之前计算的斜率从每一侧的单元中心进行外推,并使用迎风法定义面值 \(U^{pred}\)。
为了在常规(即未切割)单元的 x 面上计算 x 方向速度,我们调用
AMREX_CUDA_HOST_DEVICE_FOR_3D(ubx, i, j, k, { // X-面 Real upls = ccvel_fab(i ,j,k,0) - 0.5 * xslopes_fab(i ,j,k,0); Real umns = ccvel_fab(i-1,j,k,0) + 0.5 * xslopes_fab(i-1,j,k,0); if ( umns < 0.0 && upls > 0.0 ) { umac_fab(i,j,k) = 0.0; } else { Real avg = 0.5 * ( upls + umns ); if ( std::abs(avg) < small_vel) { umac_fab(i,j,k) = 0.0; } else if (avg >= 0) { umac_fab(i,j,k) = umns; } else { umac_fab(i,j,k) = upls; } } });
对于切割单元,我们测试面积分数是否非零:
AMREX_CUDA_HOST_DEVICE_FOR_3D(ubx, i, j, k, { // X-面 if (ax_fab(i,j,k) > 0.0) { Real upls = ccvel_fab(i ,j,k,0) - 0.5 * xslopes_fab(i ,j,k,0); Real umns = ccvel_fab(i-1,j,k,0) + 0.5 * xslopes_fab(i-1,j,k,0); if ( umns < 0.0 && upls > 0.0 ) { umac_fab(i,j,k) = 0.0; } else { Real avg = 0.5 * ( upls + umns ); if ( std::abs(avg) < small_vel) { umac_fab(i,j,k) = 0.0; } else if (avg >= 0) { umac_fab(i,j,k) = umns; } else { umac_fab(i,j,k) = upls; } } } else { umac_fab(i,j,k) = huge_vel; } });
然后我们对面心速度执行 MAC 投影,以确保它们满足
\[\nabla \cdot (\varepsilon_g U^{MAC}) = 0\]
我们通过求解以下方程实现这一点
\[\nabla \cdot \frac{\varepsilon_g}{\rho_g} \nabla \phi^{MAC} = \nabla \cdot \left( \varepsilon_g U^{pred} \right)\]
然后定义
\[U^{MAC} = U^{pred} - \frac{1}{\rho_g} \nabla \phi^{MAC}\]