0

我正在使用由另一个人编写的并行有限元代码,并且有些代码我无法理解。尤其是属于计算网格的每个节点的自由度的地图创建。网格由四边形元素组成,每个节点都有 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]));
   }
 };
4

0 回答 0