简体   繁体   English

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

[英]How do I organize these related indices into something that can be looked up efficiently in Rust?

Background 背景

In an algorithm called finite element method, a continuous region is discretized into repeated sections with consistent geometry, over which linked equations are formed based on the assumption of continuity between them. 在称为有限元法的算法中,将连续区域离散为具有一致几何形状的重复部分,并根据它们之间的连续性在其上形成链接方程。

In this case, I have chosen to divide a shape up into an arbitrary grid, and am now trying to connect the elements' values together as I iterate through the elements. 在这种情况下,我选择将形状划分为任意网格,然后在遍历元素时尝试将元素的值连接在一起。 Here is an example of the kind of grid I am talking about: 这是我正在谈论的网格类型的示例:

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

Indices 指标

There are a bunch of related indices: 有很多相关的索引:

  • The element index (teal numbers), linear, row-major, range 0..ROWS*2 . 元素索引(整数),线性,行0..ROWS*2 ,范围0..ROWS*2
  • The node index (brown numbers), linear, row-major, range 0..ROWS*COLS . 节点索引(棕色数字),线性,行0..ROWS*COLS ,范围0..ROWS*COLS
  • The local element vertex index (lavender numbers), counter-clockwise by element, range 0..2 . 局部元素顶点索引(薰衣草编号),按元素逆时针方向,范围为0..2
  • The coordinates of the actual point in space (stored with the element's struct, as well as the grid's struct) 空间中实际点的坐标(与元素的结构以及网格的结构一起存储)

Problem 问题

In order to get to the next step in the algorithm, I need to iterate over each node and compute some sums of values indexed by local element indices and store them in another matrix. 为了进入算法的下一步,我需要遍历每个节点并计算一些由局部元素索引索引的值的总和,并将它们存储在另一个矩阵中。 If, for example, I'm on node 8, my element lookup/access function is generically V(el_index, start_vertex, end_vertex) , and my matrix of outputs is S(start_node, end_node) : 例如,如果我在节点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)

and so on, for all of the connections (teal lines) from node 8. (The connections are symmetric, so once I compute S(7,8) , I don't need to compute S(8,7) .) 依此类推,对于来自节点8的所有连接(虚线)。(这些连接是对称的,因此一旦我计算出S(7,8) ,就不需要计算S(8,7) 。)

The problem is, the grid (and therefore everything else) is parameterized at runtime, so which node index + adjacency direction corresponds to which element index is dynamically determined. 问题在于,在运行时对网格(以及所有其他对象)进行了参数化,因此哪个节点索引+邻接方向对应于动态确定哪个元素索引。 I need to tell the program, "Get me the element indices where the node index of vert_x is my current node index." 我需要告诉程序“让我获取元素索引,其中vert_x的节点索引是我当前的节点索引。” That's the instruction that tells the program which element to access in V() . 这是告诉程序在V()访问哪个元素的指令。

Is there a way I can relate these indices in a simple and transparent manner in Rust? 有没有一种方法可以在Rust中以简单透明的方式关联这些索引?

Attempts 尝试次数

  1. I tried computing some simple arithmetic functions modulo the row stride of the node matrix, but the result is messy and hard to debug, as well as requiring verbose bounds checking. 我尝试计算一些简单的算术函数,以节点矩阵的行跨度为模,但是结果是混乱且难以调试的,并且需要冗长的边界检查。
  2. I tried creating three HashMap s keyed by the different vertices of each triangular element, holding the values at each vertex, but the problem is that adjacent triangles share vertex numbers as well as spatial coordinates. 我尝试创建三个由每个三角形元素的不同顶点作为键的HashMap ,并在每个顶点处保存值,但是问题是相邻的三角形共享顶点数以及空间坐标。
  3. I considered keying a HashMap with multiple keys, but the Rust docs didn't say anything about a HashMap with multiple keys. 我考虑过使用多个键来对HashMap进行键控,但是Rust文档并未对使用多个键的HashMap进行任何说明。

I think this is a possible workaround, but I hope there's something better: 我认为这是一种可能的解决方法,但我希望有更好的方法:

Nest one HashMap in another as per this question , with the node index as the first key, the element index as the second key/first value, and the element itself as the second value. 根据此问题 ,将一个HashMap嵌套在另一个HashMap中,其中节点索引为第一个键,元素索引为第二个键/第一个值,元素本身为第二个值。

So, the iteration can look like this: 因此,迭代看起来像这样:

  1. Iterate through grid node index N 遍历网格节点索引N
  2. Get all elements with N as the first key 获取所有以N作为第一个键的元素
  3. Note that the vertex indices and (relative) element indices have the following patterns, depending on where you number from: 请注意,顶点索引和(相对)元素索引具有以下模式,具体取决于您从何处编号:

    Node index numbering beginning from matrix top-left (usual in this programming domain): 从矩阵左上角开始的节点索引编号(通常在此编程域中):

     | Element (index ordinal) | Vertex | |-------------------------|--------| | 0 (min) | 1 | | 1 | 2 | | 2 | 1 | | 3 | 2 | | 4 | 0 | | 5 | 0 | 

    Node index numbering beginning as picture, from lower-left: 节点索引编号从图片开始,从左下角开始:

     | Element (index ordinal) | Vertex | |-------------------------|--------| | 0 (min) | 2 | | 1 | 0 | | 2 | 0 | | 3 | 2 | | 4 | 1 | | 5 | 1 | 

Since you can hardcode the relative order of elements like this, it might be better to use a HashMap<usize, Vec<Element>> , or even HashMap<usize, [Element; 6]> 由于您可以像这样硬编码元素的相对顺序,因此最好使用HashMap<usize, Vec<Element>>甚至HashMap<usize, [Element; 6]> HashMap<usize, [Element; 6]> . HashMap<usize, [Element; 6]>

This method brings up the question of how to relate node index to element indices dynamically. 该方法提出了如何动态地将节点索引与元素索引相关联的问题。 How do you know which elements to insert into that HashMap ? 您如何知道要在该HashMap插入哪些元素? One way to accomplish this is to record the nodes the element vertices correspond to in the element struct as well, in the same order. 实现此目的的一种方法是也以相同顺序记录元素顶点在元素结构中对应的节点。

At that point, you can compute a list like adjacent_elements as you iterate through the matrix, and use the above patterns to figure out what to access (sadly, with bounds checking). 在这一点上,你可以计算像列表adjacent_elements你迭代通过基质,并使用上述模式来弄清楚如何访问(可悲的是,用边界检查)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM