我正在使用由另一个人编写的并行有限元代码,并且有些代码我无法理解。尤其是属于计算网格的每个节点的自由度的地图创建。网格由四边形元素组成,每个节点都有 nb_dofs 自由度。网格的元素被细分为补丁,每个补丁属于不同的处理器。相邻的元素块共享相同的节点和相同的自由度。
地图按以下步骤创建。
(1) 函子“edl”是通过调用构造函数来创建的:
element_dof_list<mesh_type> edl(mesh);
其中网格是计算网格。构造函数的主体是:
element_dof_list(const mesh_type& m):mesh_m(m){},
其中 m,正如我之前所说,是用于计算的网格。
(2) 创建地图的规则是通过调用定义的:
element_mapping<mesh_type, element_dof_list<mesh_type> > e_dof_map(mesh, edl);
其中 mesh 是计算网格,edl 是在 (1) 中创建的函子。规则构造函数的主体是:
element_mapping(const mesh_type& m, const rule_type& r):mesh_m(m),rule_m(r) {}
其中,根据上面写的调用,成员mesh_m是计算网格,成员rule_m是函子edl。
(3) 最后(但这是最困难的部分),是对地图构建器的调用:
dof_map_m = make_map<shared_epetra_map>(e_dof_map);
其中 shared_epetra_map 是 Trilinos 包的共享 Epetra 映射,因为属于不同处理器的相邻元素块的自由度是共享的。e_dof_map 在 (2) 中定义。
(3) 中的调用主体是:
template<typename map_type, typename data_type>
inline map_type* make_map(const data_type& g) {
return build_map<map_type, data_type>::do_map( g );
}
其中 data_type 是 element_mapping,输入参数 g 是 e_dof_map。
这个函数调用函数
build_map<map_type, data_type>::do_map( g )
根据传入的data_type输入。
在我的情况下,输入参数 element_mapping 导致调用
template<typename map_type, typename data_type>
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
operator g()
被称为的地方。
运算符 g() 只是对所有元素和属于特定元素的所有节点的嵌套迭代,它为所有网格(称为 gid_m)提取自由度的 std::vector。正如我已经说过的,这个向量对于相邻但属于不同处理器的元素共享自由度。
因此 do_map(g()) 被 std::vector gid_m 填充。
(4) 现在出现了我无法理解的事情。致电后
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
并将 g() 作为共享自由度的 std::vector 返回,称为函数:
template<typename map_type>
struct build_map<map_type, std::valarray<int> > {
static map_type* do_map(const std::valarray<int>& gid) {
return new map_type(-1,gid.size(),&(gid[0]));
}
};
最终创建地图。
我不明白的是:
(a) 代码工程如何do_map(g())
调用
do_map(const std::valarray<int>& gid)
(b) 指令map_type(-1,gid.size(),&(gid[0]))
如何创建地图。我在我的代码中搜索过,但我没有找到任何可以根据上述信息创建地图的指令,
(-1,gid.size(),&(gid[0]))
它是标准还是 Trilinos 的功能?
我希望我足够清楚,但是所有这些调用后续结构都让我发疯。有人想帮助我吗?
我不能问编写代码的人,因为他忘记了所有这些调用链(自从他编写代码以来已经过去了一段时间,现在他正在另一个地方从事其他事情)。
您对共享 epetra 地图的构造函数是正确的,我检查了 trilinos 的 epetra 包,并且有一个构造函数作为参数
(-1,gid.size(),&(gid[0])).
但我无法理解的是如何从调用到
struct build_map {
static map_type* do_map(const data_type& g){
return build_map<map_type, typename data_type::result_type>::do_map(g());
}
};
其中operatot g() 返回一个std::vector,它被自动调用函数:
template<typename map_type>
struct build_map<map_type, std::valarray<int> > {
static map_type* do_map(const std::valarray<int>& gid) {
return new map_type(-1,gid.size(),&(gid[0]));
}
};