美文网首页
# `libmesh` 迭代器的实现和方法(2)

# `libmesh` 迭代器的实现和方法(2)

作者: 不想当社畜 | 来源:发表于2019-12-14 11:23 被阅读0次

libmesh 迭代器的实现和方法(2)

由于两个类不同的迭代器都是存在四个函数的实现,主要包括beginend的两种结果实现(non-constconst)。由于两种实现方法都是一样的,只是解决的返回值不同,所以只针对non-const结果进行分析。

libmesh中具体某个迭代器的实现

主要是查看elementsactive_local_elements这两个迭代器结构的实现,他们分别代表了所有单元的迭代器begin-end本地processer单元begin-end。应该在针对DistributedMesh类中,Elem对象都是使用mapvector<Elem *, dof_id_type> _elements;的方式进行存储的,所以需要知道如何实现两个问题的。

查看mesh_iterator.C中的实现,对宏进行提取出来,得到如下代码(针对DistributedMesh类展开):

// 宏的定义(只有non-const返回值的定义)
#define INSTANTIATE_ELEM_ACCESSORS(FUNC_PREFIX, PRED, FUNC_ARG, ...)    \
DistributedMesh::element_iterator                                     \
  DistributedMesh::FUNC_PREFIX##_begin (FUNC_ARG)                       \
  {                                                                     \
    return element_iterator(_elements.begin(), _elements.end(), Predicates::PRED<elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  DistributedMesh::element_iterator                                     \
  DistributedMesh::FUNC_PREFIX##_end (FUNC_ARG)                         \
  {                                                                     \
    return element_iterator(_elements.end(), _elements.end(), Predicates::PRED<elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \

// 实例化
INSTANTIATE_ELEM_ACCESSORS(elements,                        NotNull,              EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(active_local_elements,           ActiveLocal,          EMPTY,                          this->processor_id())
  
// 其中 定义了如下宏(说明EMPTY 为空)
# define EMPTY 

INSTANTIATE_ELEM_ACCESSORS宏进行解析

根据宏调用的参数INSTANTIATE_ELEM_ACCESSORS(FUNC_PREFIX, PRED, FUNC_ARG, ...)其中FUNC_PREFIX为实例化方法的前缀(elements或者active_local_elements)。根据宏中##的符号可以连接成字符的特性,与FUNC_PREFIX##_beginFUNC_PREFIX_end通过宏的展开形成elements_beginelements_end两个对应类的方法。宏中具体内容就是方法的实现。

而宏中还有三个其他参数PRED,FUNC_ARG,...;其中PRED表示Predicates命名空间的对应的类用来实现不同要求迭代器的实现,FUNC_ARG则表示FUNC_PREFIX##_begin方法对应参数列表,而...表示是宏中表示的可变参数,在宏内部使用__VA_ARGS__变量表示使用该可变参数(在activate_local_elements的实现中有用到这个特性,this->processor_id())。通过引入##...能将宏应用的特别强大,适应能力特别强。

针对elementsactivate_local_elements迭代器实现

elements是针对本模型所有单元的单元迭代器,而activate_local_elements是针对模型中当前的CPUprocesser中的单元迭代器,由于DistributedMesh对象是分布式存储信息存储的,所以上述两个迭代器的返回结果肯定不一样的。

elementsactivate_local_elements迭代器的代码进行展开如下:

// elements迭代器(返回模型中所有迭代器)
DistributedMesh::element_iterator     
DistributedMesh::elements_begin ()                       
  {                                                                     
    return element_iterator(_elements.begin(), _elements.end(), Predicates::NotNull<elem_iterator_imp>()); 
  }                                                                     
  DistributedMesh::element_iterator                                     
  DistributedMesh::elements_end ()                         
  {                                                                     
    return element_iterator(_elements.end(), _elements.end(), Predicates::NotNull<elem_iterator_imp>()); 
  }       
// activate迭代器 (返回模型中当前进程下的单元)
DistributedMesh::element_iterator                                     
  DistributedMesh::activate_local_elements_begin ()                       
  {                                                                     
    return element_iterator(_elements.begin(), _elements.end(), Predicates::ActiveLocal<elem_iterator_imp>(this->processor_id())); 
  }                                                                     
  DistributedMesh::element_iterator                                     
  DistributedMesh::activate_local_elements_end ()                         
  {                                                                     
    return element_iterator(_elements.end(), _elements.end(), Predicates::ActiveLocal<elem_iterator_imp>(this->processor_id())); 
  }                                                                     


根据宏进行展开后,可以看出elementsactivate_local_elements对应的两个迭代器begin,end的返回值类型都是DistributedMesh类中定义的单元迭代器element_iterator

同时两种不同功能(遍历本地,遍历全局)的迭代器的参数都是_elements对象(该参数在DistributedMesh中使用mapvector进行存放的数据),此时是否能够说明_elements是否存放的是完整的数据对象呢?还是在遍历全局的过程中,存在MPI广播或者同步呢?

根据两种功能宏展开的函数内容上看,要实现两种功能主要是根据Predicates::NotNullPredicates::ActiveLocal两者实现的,与_elements数据存放无关,但是此时暂时无法知道mapvector<Elem*,Dof_id_type> _elements数据存放的形式,是在本地仅存放所有单元的信息,还是局部?


进一步了解:

  • elements_iterator的实现和作用
  • Predicates命名空间的作用(其中主要包括单元迭代器不同功能的实现)

相关文章

网友评论

      本文标题:# `libmesh` 迭代器的实现和方法(2)

      本文链接:https://www.haomeiwen.com/subject/jvscnctx.html