在 MFIX-Exa 中构建嵌入边界
MFIX-Exa 允许使用 4 种方法来指定嵌入边界(EBs)。
使用原生 AMReX cpp 函数。
使用 CSG 文件格式。
使用平面壁。
使用 STL 文件格式。
还有两个影响水平集创建的参数(在 inputs
文件中指定):
参数 |
描述 |
---|---|
|
如果大于 0,MFIX-Exa 以多级模式运行。 水平集网格遵循所有其他网格。如果等于 1, 则水平集有两个级别(一个具有更高细化的 额外级别)。 |
|
如果 |
EB 规范
原生 AMReX 函数
MFIX-Exa 使用在命名空间 amrex::EB2
中定义的 AMReX 的构造实体几何框架。有关详细信息,请参阅 AMReX EB 文档 。这些在 src/eb/mfix_eb.cpp
中定义。函数 mfix::make_eb_geometry
(也在 src/eb/mfix_eb.cpp
中定义)根据 inputs
文件中的 mfix.geometry
设置的值选择以下几何之一。
描述 |
|
---|---|
箱体(最多六面墙) |
|
圆柱 |
|
漏斗 |
|
通用 |
|
Generic
几何规范需要用户在src/eb.mfix_eb_generic.cpp
中实现。此外,请参阅 AMReX 几何文档 以获取有关如何使用构造实体几何方法构建新几何的信息。
CSG 文件格式
或者,可以使用 OpenSCAD 的 CSG 文件格式创建构造实体几何,方法是安装 csg-eb
库。要使用此选项,MFIX-Exa 必须在构建时使用标志 MFIX_CSG=TRUE
,并在 inputs
中设置选项 mfix.geom_type = csg
和 mfix.geometry_filename
。有关此格式的更多详细信息,请参阅 CSG-EB 仓库。
平面壁
可以在 inputs
文件中指定平面边界条件。即使用户在 inputs
中未指定 mfix.geometry
或 mfix.geometry_filename
,任何无滑移或自由滑移边界条件都表示为 EB 壁。
STL 文件格式
可以使用多种 CAD 程序创建的标准三角形语言(STL)文件来指定 EB 几何。要使用此方法,必须在 inputs
中设置选项 mfix.geom_type = stl
和 mfix.geometry_filename
。
MFIX-Exa 如何构建 EB 几何
一旦在 inputs
文件中指定了几何,所有几何的过程都是相同的。
构建表示几何的隐式函数。
调用
mfix::build_eb_levels(gshop)
该函数构建 EB 级别。注意,这也使颗粒 EB 级别指向流体 EB 级别。调用
mfix.fill_eb_levelsets
。此函数填充水平集MultiFab
。
MFIX-Exa 的 EB 数据结构
mfix
类存储以下 EB 数据:
//! 代表流体边界条件的 EB 级别
Vector<const EB2::Level *> eb_levels;
//! 代表颗粒边界条件的 EB 级别(与 `mfix::eb_levels` 相同,但可能包括额外的墙)。
Vector<const EB2::Level *> particle_eb_levels;
//! 存在于流体网格上的 EB 工厂
Vector< std::unique_ptr<amrex::EBFArrayBoxFactory> > ebfactory;
//! 存在于颗粒网格上的 EB 工厂
Vector< std::unique_ptr<amrex::EBFArrayBoxFactory> > particle_ebfactory;
如上一小节所述,mfix::eb_levels
和 mfix::particle_eb_levels
之间的区别使用户能够仅为颗粒指定修改后的 EB 几何。而流体会在 mfix::eb_levels
中看到 EB 几何。如果未指定额外的颗粒 EB 几何(上一节的第 4 点),则 mfix::particle_eb_levels
指向 mfix::eb_levels
。
同样,mfix::ebfactory
是在流体网格上构建并使用流体 EB 级别,而 mfix::particle_ebfactory
是在颗粒网格上使用颗粒 EB 级别构建的。
关于构建 EB 级别的说明
MFIX-Exa 在 mfix::build_eb_levels
中构建 EB 级别(通过 LSCore<F>::BuildEBLevel
)
EB2::Build(gshop, geom[lev], required_crse_lev, max_crse_level);
const EB2::IndexSpace & ebis = EB2::IndexSpace::top();
在构建 EB 级别时,需要指定最大粗化级别 (int max_crse_level
) 和所需粗化级别 (int required_crse_lev
)。这样做的原因是我们需要指定 EB 仍然定义在哪个粗化级别。这可能不是立即显而易见的,但泊松求解器(用于流体求解)也间接依赖于这些参数。因此,在创建 EB 级别时更改这些参数可能会限制 MLMG 求解器可以使用的级别数量,从而在流体求解中给出略有不同的答案。
在壁面处的局部网格细化
MFIX-Exa 具有在 EBs 附近局部细化计算网格的能力。这是通过标记(在 mfix::ErrorEst
中)体积分数介于 0 和 1 之间的任何单元来完成的。要启用局部网格细化,请将 amr.max_level
设置为大于 1 的值。请注意,参数 mfix.levelset__refinement
在所有情况下都被忽略,除非 amr.max_level = 1
。
MFIX-Exa 初始化过程
由于 MFIX-Exa 在构建网格时需要体积分数(因为这是 mfix::ErrorEst
所需的),因此在调用 mfix::Init
之前需要构建 EB 几何。因此,推荐的过程是
// 默认构造函数(geom[lev] 在此处定义)
mfix my_mfix;
// 从 ParamParse 数据库初始化内部参数
my_mfix.InitParams(solve_fluid, solve_dem, call_udf);
// 初始化数据数组内部的内存
my_mfix.ResizeArrays();
// 构建 EB(必须在 mfix::Init 之前完成)
my_mfix.make_eb_geometry();
// 初始化派生的内部参数。在此处创建网格。
my_mfix.Init(dt, time);
// 在新网格上创建 EB 工厂
my_mfix.make_eb_factories();
if (solve_dem)
{
// 在每个级别上填充水平集(必须在 mfix::Init 之后完成)
my_mfix.fill_eb_levelsets();
}
// 完成构建级别
my_mfix.InitLevelData(dt, time);
// 重网格(确保所有 MultiFabs 都在其正确的网格上)
my_mfix.Regrid();
还请注意,mfix 也在 Fortran 中定义了边界条件(通过 mfix.dat)。由于这些可能需要用于构建 EB 墙,mfix::make_eb_geometry
也会调用 mfix_set_bc_type
。
每个级别的网格是在 mfix::Init
中通过调用从 amrex::AmrCore
继承的初始化函数构建的。
// 这告诉 AmrMesh 类在创建初始网格层次结构时不进行迭代
SetIterateToFalse();
// 这告诉 Cluster 例程使用新的分割例程,如果它们不能提高效率,则拒绝分割
SetUseNewChop();
// 这构建了新的网格
InitFromScratch(0.);
水平集函数
MFIX-Exa 使用水平集函数来解决颗粒-壁面碰撞。有关详细信息,请参阅 AMReX 水平集文档。水平集函数存储在节点 Vector<std::unique_ptr<MultiFab>> mfix::level_sets
上。水平集数据始终存储在颗粒网格上。根据输入 amr.max_level
水平集可以处于两种模式之一:
MFIX-Exa 以单级模式运行 (
nlev == 1
)。然后mfix::level_sets[0]
将与流体的分辨率相同(除了它存储在颗粒网格上)。即使nlev == 1
,也有第二个级别,level_sets[1]
。该级别与level_sets[0]
相同,但经过mfix::levelset__refinement
的细化。这样,即使流体定义在相当粗的网格上,水平集也始终具有适当的分辨率来解析 EB 中的结构。MFIX-Exa 以多级模式运行 (
nlev > 1
)。参数mfix::levelset__refinement
被忽略。mfix::level_sets
然后遵循 MFIX-Exa 的其余部分,即它在所有级别的颗粒网格上定义。
水平集在两个地方使用:
函数
MFIXParticleContainer::EvolveParticles
将水平集插值到每个颗粒的位置,以解决与 EBs 的碰撞。如果nlev == 1
,则使用level_sets[1]
来演化颗粒位置。否则,每个级别使用level_sets[lev]
。流体-颗粒耦合有时会依赖于邻居模板,其中一个或多个单元被 EB 覆盖。为了避免不符合边界条件的值,流体速度在这些单元中被重建。该算法依赖于水平集,并在每个级别上使用
level_sets[lev]
。
涉及水平集的特殊情况
水平集函数由 mfix::fill_eb_levelsets()
函数填充。涉及水平集的两种特殊情况:
质量流入边界条件没有给出 EB 墙。然而,我们也不希望颗粒从 MI 中掉落,因此在
mfix::fill_eb_levelsets()
函数的最后,我们调用mfix::intersect_ls_walls()
。这会在每个 MI 处执行与表示墙的水平集的交集操作。箱体几何和常规几何完全由平面表面组成。因此,水平集不是由 EB 工厂构建的(如所有其他几何的情况)。而是与所有平面表面的交集。这具有正确描述角落的优点。