如何将这些相关索引组织成可以在Rust中高效查找的内容?

bri*_*tar 5 iteration algorithm geometry hashmap rust

背景

在一种称为有限元方法的算法中,将连续区域离散化为具有一致几何的重复区域,在该区域上基于它们之间的连续性假设形成链接方程.

在这种情况下,我选择将形状划分为任意网格,现在我尝试将元素的值连接在一起,因为我遍历元素.这是我正在讨论的网格类型的示例:

示例网格改编自https://people.sc.fsu.edu/~jburkardt/m_src/fem2d_poisson_rectangle/rectangle_elements.png

指数

有一堆相关的指数:

  • 元素索引(蓝绿色数字),线性,行主要,范围0..ROWS*2.
  • 节点索引(棕色数字),线性,行主要,范围0..ROWS*COLS.
  • 局部元素顶点索引(淡紫色数字),按元素逆时针,范围0..2.
  • 空间中实际点的坐标(存储在元素的结构中,以及网格的结构)

问题

为了进入算法的下一步,我需要迭代每个节点并计算由局部元素索引索引的一些值的总和,并将它们存储在另一个矩阵中.例如,如果我在节点8上,我的元素查找/访问功能是一般的V(el_index, start_vertex, end_vertex),我的输出矩阵是S(start_node, end_node):

  1. S(8,8) = V(el_14, vert_1, vert_1) + V(el_15, vert_1, vert_1) + V(el_04, vert_0, vert_0) + V(el_03, vert_0, vert_0) + V(el_2, vert_2, vert_2) + V(el_13, vert_2, vert_2)
  2. S(8,9) = V(el_15, vert_1, vert_2) + V(el_4, vert_0, vert_2)

等等,对于来自节点8的所有连接(蓝绿色线).(连接是对称的,所以一旦我计算S(7,8),我就不需要计算S(8,7).)

问题是,网格(以及其他所有其他)在运行时被参数化,因此哪个节点索引+邻接方向对应于动态确定哪个元素索引.我需要告诉程序,"获取元素索引,其中节点索引vert_x是我当前的节点索引." 这是指示程序访问哪个元素的指令V().

有没有办法在Rust中以简单透明的方式将这些索引联系起来?

尝试

  1. 我尝试计算一些简单的算术函数,以模块节点矩阵的行步长为模,但结果很混乱,难以调试,并且需要详细的边界检查.
  2. 我尝试创建三个HashMap由每个三角形元素的不同顶点键入的s,保持每个顶点的值,但问题是相邻的三角形共享顶点数和空间坐标.
  3. 我考虑HashMap用多个键来键入一个键,但Rust文档没有说任何关于HashMap多键的说法.

bri*_*tar 0

我认为这是一个可能的解决方法,但我希望有更好的方法:

HashMap根据这个问题,将一个嵌套在另一个中,节点索引作为第一个键,元素索引作为第二个键/第一个值,元素本身作为第二个值。

因此,迭代可以如下所示:

  1. 遍历网格节点索引N
  2. N获取所有以第一个键为键的元素
  3. 请注意,顶点索引和(相对)元素索引具有以下模式,具体取决于您编号的位置:

    节点索引编号从矩阵左上角开始(通常在此编程领域中):

    | Element (index ordinal) | Vertex |
    |-------------------------|--------|
    | 0 (min)                 | 1      |
    | 1                       | 2      |
    | 2                       | 1      |
    | 3                       | 2      |
    | 4                       | 0      |
    | 5                       | 0      |
    
    Run Code Online (Sandbox Code Playgroud)

    节点索引编号如图所示,从左下开始:

    | Element (index ordinal) | Vertex |
    |-------------------------|--------|
    | 0 (min)                 | 2      |
    | 1                       | 0      |
    | 2                       | 0      |
    | 3                       | 2      |
    | 4                       | 1      |
    | 5                       | 1      |
    
    Run Code Online (Sandbox Code Playgroud)

由于您可以像这样对元素的相对顺序进行硬编码,因此最好使用HashMap<usize, Vec<Element>>, 甚至HashMap<usize, [Element; 6]>

这种方法提出了如何动态地将节点索引与元素索引相关联的问题。您如何知道要插入哪些元素HashMap?实现此目的的一种方法是在元素结构中也以相同的顺序记录元素顶点对应的节点。

此时,您可以像adjacent_elements迭代矩阵一样计算列表,并使用上述模式来确定要访问的内容(遗憾的是,需要进行边界检查)。