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

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

作者: 不想当社畜 | 来源:发表于2019-12-13 21:00 被阅读0次

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

在阅读libmesh源码的过程中,会接触到两个类:DistributedMeshReplicatedMesh,它们都是用来存放有限元问题的模型数据(主要包括问题离散后的节点Node单元Elem数据)。两个类主要的不同在于它们存放节点Node单元Elem数据方式不同。由于libmesh主要面向的高性能计算的用户,其主要的用户计算的模型主要是大规模的实际工程问题,所以实际在程序计算过程中,需要多个CPU核同时进行计算。ReplicatedMesh类主要在存放NodeElem的过程中,每个CPUprocesser都会存放完整的一套NodeElem数据,但是每个CPUprocesser参与处理和计算的NodeElem都是整套数据的部分,因此存在大量的数据存储浪费.而DistributedMesh在存放NodeElem过程中,采用分布式存放的方式进行数据的存放,每个CPUProcesser仅仅存放跟本Processer计算相关的NodeElem的数据,这样能保证程序在计算内存中大大的减少.

在阅读libmesh代码的mesh对象时,其定义了一个抽象基类MesBbase,该类中主要是定义了mesh类大概需要的一些函数接口(API).然后通过使用UnstructuredMesh对象主要是声明了mesh对象的基础功能,读写入文件等。

mesh对象的继承关系如下:

DistributedMesh  -- 
                   |-- > UnstructuredMesh -> MeshBase 
ReplicatedMesh   -- 

libmeshmesh对象的迭代器使用

DistributedMesh类中存放Elem数据使用的是自定义的mapvector进行存放,其底层使用的是std::map<Elem *,Dof_id_type>进行数据存放(此处不知道为何分布式存放的方式需要使用Key-value的模式)。与之对应的是ReplicatedMesh类在存放Elem数据使用的是std::vector<Elem *>,由于针对该类型每个Processer都存放了完整的Elem数据,因此只要保证每个processer对应Elem数据都相同即可(包括单元序号,顺序,大小完全一模一样).使用std::vector<Elem *>存放完全可以理解。但是DistributedMesh使用std::map方式存放的原因暂时不太清楚。

说明:elem数据和Node数据都是类似的,所以清楚了Elem等于清楚了Node的迭代模式。

由于在两个类都是继承自最基础的MeshBase类,而该类定义了大量的迭代器函数,包括单元迭代器和节点迭代器。根据不同的实现功能不同进行区分:

// 正常的单元迭代器
virtual element_iterator elements_begin () = 0;
virtual element_iterator elements_end () = 0;
virtual const_element_iterator elements_begin () const = 0;
virtual const_element_iterator elements_end () const = 0;

// 遍历所有elem->ancestor() 为true的单元 (具体功能不太清楚)
virtual element_iterator ancestor_elements_begin () = 0;
virtual element_iterator ancestor_elements_end () = 0;
virtual const_element_iterator ancestor_elements_begin () const = 0;
virtual const_element_iterator ancestor_elements_end () const = 0;

// ...

由于上面定义都是抽象类,所以在DistributedMeshReplicatedMesh类的定义中都已经override覆盖了原始的定义(在对应类的声明定义中,只有对应迭代器的声明,没有函数定义和实现,一直很奇怪,通过生成的可执行程序进行debug调试,终于找到两个类所有迭代器的实现,在mesh_iterator.C文件).

libmesh中迭代器的定义

LibmeshMeshBase类迭代器的定义和实现是在mesh_iterator.C文件中实现的,而且其应用了C语言中宏的方式实现的。

其中宏的定义如下:

// 单元 (同理节点也是一样的)
#define INSTANTIATE_ELEM_ACCESSORS(FUNC_PREFIX, PRED, FUNC_ARG, ...)    \
  ReplicatedMesh::element_iterator                                      \
  ReplicatedMesh::FUNC_PREFIX##_begin (FUNC_ARG)                        \
  {                                                                     \
    return element_iterator(_elements.begin(), _elements.end(), Predicates::PRED<elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  ReplicatedMesh::const_element_iterator                                \
  ReplicatedMesh::FUNC_PREFIX##_begin (FUNC_ARG) const                  \
  {                                                                     \
    return const_element_iterator(_elements.begin(), _elements.end(), Predicates::PRED<const_elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  ReplicatedMesh::element_iterator                                      \
  ReplicatedMesh::FUNC_PREFIX##_end (FUNC_ARG)                          \
  {                                                                     \
    return element_iterator(_elements.end(), _elements.end(), Predicates::PRED<elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  ReplicatedMesh::const_element_iterator                                \
  ReplicatedMesh::FUNC_PREFIX##_end (FUNC_ARG) const                    \
  {                                                                     \
    return const_element_iterator(_elements.end(), _elements.end(), Predicates::PRED<const_elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  DistributedMesh::element_iterator                                     \
  DistributedMesh::FUNC_PREFIX##_begin (FUNC_ARG)                       \
  {                                                                     \
    return element_iterator(_elements.begin(), _elements.end(), Predicates::PRED<elem_iterator_imp>(__VA_ARGS__)); \
  }                                                                     \
  DistributedMesh::const_element_iterator                               \
  DistributedMesh::FUNC_PREFIX##_begin (FUNC_ARG) const                 \
  {                                                                     \
    return const_element_iterator(_elements.begin(), _elements.end(), Predicates::PRED<const_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__)); \
  }                                                                     \
  DistributedMesh::const_element_iterator                               \
  DistributedMesh::FUNC_PREFIX##_end (FUNC_ARG) const                   \
  {                                                                     \
    return const_element_iterator(_elements.end(), _elements.end(), Predicates::PRED<const_elem_iterator_imp>(__VA_ARGS__)); \
  }

针对两种类(DistributedMeshReplicatedMesh)的函数接口都有四种实现,都是分别于类的声明的中的实现是一致的(包括beginend两种迭代器,同时两种迭代器的分别有const返回和non-const返回值的区别)。

virtual element_iterator elements_begin () = 0;
virtual element_iterator elements_end () = 0;
virtual const_element_iterator elements_begin () const = 0;
virtual const_element_iterator elements_end () const = 0;

其中Elem的各种迭代器函数的实现(根据宏的定义):elem,active_elements,ancestor_elements...等等.代码实现如下:

INSTANTIATE_ELEM_ACCESSORS(elements,                        NotNull,              EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(active_elements,                 Active,               EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(not_active_elements,             NotActive,            EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(ancestor_elements,               Ancestor,             EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(not_ancestor_elements,           NotAncestor,          EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(subactive_elements,              SubActive,            EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(not_subactive_elements,          NotSubActive,         EMPTY,                          EMPTY)
INSTANTIATE_ELEM_ACCESSORS(local_elements,                  Local,                EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(semilocal_elements,              ActiveSemiLocal,      EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(active_semilocal_elements,       ActiveSemiLocal,      EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(facelocal_elements,              FaceLocal,            EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(not_local_elements,              NotLocal,             EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(active_local_elements,           ActiveLocal,          EMPTY,                          this->processor_id())
INSTANTIATE_ELEM_ACCESSORS(active_not_local_elements,       ActiveNotLocal,       EMPTY,                          this->processor_id())

根据宏的展开,分别实现了对应类函数接口的实现功能.

相关文章

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

    libmesh 迭代器的实现和方法(1) 在阅读libmesh源码的过程中,会接触到两个类:Distributed...

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

    libmesh 迭代器的实现和方法(2) 由于两个类不同的迭代器都是存在四个函数的实现,主要包括begin和end...

  • 9-1 自定义迭代器

    迭代对象和迭代器是实现了 __iter__ 方法的 而迭代器是额外还需要实现了 __next__ 方法的 可迭代对...

  • Python 进阶之迭代器, 生成器

    一.迭代器(iterator) 迭代器 :任何实现了 __iter__ 和 __next__方法的对象都是迭代器....

  • 迭代器、生成器

    迭代器对象 实现了迭代器协议的对象叫做迭代器对象,迭代器对象可以使用 next 和 __next__ 方法进行迭...

  • 面试题三(3)

    1.什么叫 迭代器?(1)迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会...

  • python进阶——2. 对象迭代与反迭代技巧

    2.1 迭代器和可迭代对象 迭代器是指继承自Iterator,并实现了next方法的对象。使用迭代器的好处是节省内...

  • 第7章迭代器模式

    第7章迭代器模式 7.1 jQuery中的迭代器 7.2 实现自己的迭代器 7.3 内部迭代和外部迭代 1内部迭代...

  • 2-1迭代对象、迭代器、生成器

    可迭代对象、迭代器和生成器的关系 可迭代对象 可迭代对象实现某种接口,对与列表内部实现了__iter__()方法,...

  • 5、迭代器实现

    闭包实现迭代器 迭代函数实现迭代器 --1,调用迭代函数,(把状态变量和控制变量当做参数传递给迭代函数) 状态变...

网友评论

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

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