How to organize these related indexes into something that can be effectively found in Rust?

Background

In an algorithm called the finite element method, a continuous region is discretized into repeating sections with a consistent geometry, which form related equations based on the assumption of continuity between them.

In this case, I decided to split the shape into an arbitrary grid, and now I'm trying to connect the values โ€‹โ€‹of the elements together when I iterate over the elements. Here is an example of such a grid, which I am talking about:

Grid example adapted from https://people.sc.fsu.edu/~jburkardt/m_src/fem2d_poisson_rectangle/rectangle_elements.png

Indices

There are a number of related indexes:

  • Element index (number of tians), linear, row of rows, range 0..ROWS*2 .
  • Index node (brown numbers), linear, row row, range 0..ROWS*COLS .
  • The local index of the vertices (lavender numbers), counterclockwise on the element, is in the range 0..2 .
  • The coordinates of the actual point in space (stored along with the struct element, as well as with the grid)

Problem

To move on to the next step of the algorithm, I need to iterate over each node and calculate some sums of values โ€‹โ€‹indexed by indices of local elements, and save them in another matrix. If, for example, I am on node 8, my element / access search function is generally V(el_index, start_vertex, end_vertex) , and my output matrix is S(start_node, end_node) :

  • 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)
  • S(8,9) = V(el_15, vert_1, vert_2) + V(el_4, vert_0, vert_2)

etc. for all connections (teal lines) from node 8. (The connections are symmetrical, so as soon as I calculate S(7,8) , I don't need to calculate S(8,7) .)

The problem is that the grid (and therefore everything else) is parameterized at run time, so the direction of the node index + adjacency corresponds to which element index is dynamically determined. I need to tell the program: "Get me the element indices, where the node vert_x is my current node index." This is an instruction that tells the program which element has access to V() .

Is there a way to relate these indexes in a simple and transparent way in Rust?

Attempts

  • I tried to compute some simple arithmetic functions modulo the row pitch of the matrix node, but the result is dirty and hard to debug, and also requires checking for detailed estimates.
  • I tried to create three HashMap that were tied to different vertices of each triangular element, storing values โ€‹โ€‹at each vertex, but the problem is that neighboring triangles contain vertex numbers as well as spatial coordinates.
  • I considered keying a HashMap with multiple keys, but Rust docs did not say anything about HashMap with multiple keys.
+5
source share
1 answer

I think this is a possible workaround, but I hope something better is there:

Configure one HashMap in another like 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.

So the iteration might look like this:

  • Iterate through a grid node index N
  • Get all items with N as the first key
  • Note that vertex indices and (relative) element indices have the following patterns, depending on where you are listed:

    Node index numbering, starting with the matrix from top to left (usually in this programming area):

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

    Node index numbering starting as an image, bottom left:

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

Since you can rigidly set the relative order of elements like this, itโ€™s better to use HashMap<usize, Vec<Element>> or even HashMap<usize, [Element; 6]> HashMap<usize, [Element; 6]> .

This method asks how to dynamically associate node index indexes with element index. How do you know which elements to embed in this HashMap ? One way to achieve this is to record the nodes whose vertices correspond in the structure of the element in the same order.

At this point, you can compute a list, such as adjacent_elements , when you iterate over the matrix, and use the above patterns to figure out what to call (unfortunately, with border checking).

0
source

Source: https://habr.com/ru/post/1263847/


All Articles