Wrong adjacencies after adding new element

Issue #163 new
olivier jamond created an issue

In the following code snippet, I got problem with adjacency queries:

I first create a qua4 q4, and get the handle of its first edge e2. I check that the adjacencies of this edge to entities of dimension 2 gives a single value (which is q4). Then I create a new element: an edge whose nodes are the 2 first nodes of q4. I re-ask for the adjacencies of e2 to entities of dimension 2 (expecting to have the same result as before: q4), but this time I got nothing…

#include <moab/Core.hpp>

#include <iostream>
#include <vector>

int main() {

  moab::Core mb;
  mb.set_dimension(2);

  std::vector<std::vector<double>> coords = {
      {0., 0., 0.}, {1., 0., 0.}, {1., 1., 0.}, {0., 1., 0.}};

  std::vector<moab::EntityHandle> vertices;
  for (const auto &c : coords) {
    moab::EntityHandle h;
    mb.create_vertex(c.data(), h);
    vertices.push_back(h);
  }

  moab::EntityHandle q4;
  mb.create_element(moab::MBQUAD, vertices.data(), 4, q4);

  std::vector<moab::EntityHandle> adj;
  mb.get_adjacencies(&q4, 1, 1, true, adj);

  auto e2 = adj[0];

  auto show = [&](const std::string &title) {
    adj.clear();
    mb.get_adjacencies(&e2, 1, 2, true, adj);
    std::cout << "\n\n"
              << "-----------------------------------------------\n" << title
              << ":\n\ncells attached to e2 edge: [";
    for (const auto &h : adj) {
      std::cout << h << " ";
    }
    std::cout << "]\n\n";

    mb.print_database();
    std::cout << "-----------------------------------------------\n";
  };

  show("BEFORE ADDING NEW EDGE");

  moab::EntityHandle foo;
  mb.create_element(moab::MBEDGE, vertices.data(), 2, foo);

  show("AFTER ADDING NEW EDGE");

  return 0;
}

Here is the screen output of this snippet:

-----------------------------------------------
BEFORE ADDING NEW EDGE:

cells attached to e2 edge: [3458764513820540929 ]

  Vertex ID  X        Y        Z        Adjacencies   
  ---------- -------- -------- -------- -----------...
(Sequence [1,4] in SequenceData [1,524288])
           1        0        0        0  Edge 1 4  Quad 1
           2        1        0        0  Edge 1 2  Quad 1
           3        1        1        0  Edge 2 3  Quad 1
           4        0        1        0  Edge 3 4  Quad 1
     Edge ID Connectivity Adjacencies
  ---------- ------------ -----------...
(Sequence [1,4] in SequenceData [1,524288])
           1    1    2  
           2    2    3  
           3    3    4  
           4    4    1  
     Quad ID Connectivity         Adjacencies
  ---------- -------------------- -----------...
(Sequence [1,1] in SequenceData [1,524288])
           1    1    2    3    4
-----------------------------------------------


-----------------------------------------------
AFTER ADDING NEW EDGE:

cells attached to e2 edge: []

  Vertex ID  X        Y        Z        Adjacencies   
  ---------- -------- -------- -------- -----------...
(Sequence [1,4] in SequenceData [1,524288])
           1        0        0        0  Edge 1 4 5  Quad 1
           2        1        0        0  Edge 1 2 5  Quad 1
           3        1        1        0  Edge 2 3  Quad 1
           4        0        1        0  Edge 3 4  Quad 1
     Edge ID Connectivity Adjacencies
  ---------- ------------ -----------...
(Sequence [1,5] in SequenceData [1,524288])
           1    1    2  
           2    2    3  
           3    3    4  
           4    4    1  
           5    1    2  
     Quad ID Connectivity         Adjacencies
  ---------- -------------------- -----------...
(Sequence [1,1] in SequenceData [1,524288])
           1    1    2    3    4
-----------------------------------------------

Thanks for helping!

Comments (8)

  1. Iulian Grindeanu

    thank you for pointing this out;
    It is an issue with “equivalent” entities; the new edge (entity id 5) is equivalent to edge with entity id 1; (they have the same connectivity, vertices 1 and 2).
    In that case, adjacency is retrieved from the explicit adjacencies, which shows nothing, unless you add that adjacency explicitly, with something like
    mb.add_adjacencies(e2, &q4, 1, true);

    Explicit adjacencies show up also in the “print_database” method on the last column for each entity.

    @Tim Tautges @Vijay M Do you have any suggestion/insight why is this the behavior ?

    The behavior I don’t get is about entities that have the same connectivity and definition, they are on top of each other. In our jargon, they are “equivalent”. (edge 1 and 5 in the above example) Only in that case, adjacency information is obtained from what we call “explicit adjacency”, and it does not follow our regular, vertex-based adjacency.

    In the vertex-based adjacency, we store for each vertex an ordered std::vector of entity handles that are connected to that vertex. All adjacencies are derived from that. For example, to get 2d cells adjacent to an edge, we first get the vertices of the edge, then we intersect the vectors of the entities adjacent to each vertex, that are of dimension 2. In other words, we go down to vertices, then up to the desired dimension.

    We can add “explicit” adjacency to any entity, by using “add_adjacencies” type method. This is to save time, I assume, if that adjacency is requested many times.
    I do not like this behavior, and I do not understand why it is going there only for the “equivalent” entities. I would completely eliminate the explicit adjacency, as it is confusing in my opinion. There are other issues with explicit adjacencies that I do not like, related to I/O

    @Vijay M @Tim Tautges ?

  2. olivier jamond reporter

    Thanks for your answer.

    Just to add a remark to the issue: the behavior is the same if the 2 edges on top of each other do not have the same connectivity. In the following, one of the 2 is 2nd order and so has a middle point, whereas the other is 1rt order (but the 2 edges have the same “end points”).

    #include <moab/Core.hpp>
    
    #include <iostream>
    #include <vector>
    
    int main() {
    
      moab::Core mb;
      mb.set_dimension(2);
    
      std::vector<std::vector<double>> coords = {
          {0., 0., 0.}, {1., 0., 0.}, {1., 1., 0.}, {0., 1., 0.},
          {.5, 0., 0.}, {1., .5, 0.}, {.5, 1., 0.}, {0., .5, 0.}};
    
      std::vector<moab::EntityHandle> vertices;
      for (const auto &c : coords) {
        moab::EntityHandle h;
        mb.create_vertex(c.data(), h);
        vertices.push_back(h);
      }
    
      moab::EntityHandle q8;
      mb.create_element(moab::MBQUAD, vertices.data(), 8, q8);
    
      std::vector<moab::EntityHandle> adj;
      mb.get_adjacencies(&q8, 1, 1, true, adj);
    
      auto e3 = adj[0];
    
      auto show = [&](const std::string &title) {
        adj.clear();
        mb.get_adjacencies(&e3, 1, 2, true, adj);
        std::cout << "\n\n"
                  << "-----------------------------------------------\n" << title
                  << ":\n\ncells attached to e3 edge: [";
        for (const auto &h : adj) {
          std::cout << h << " ";
        }
        std::cout << "]\n\n";
    
        mb.print_database();
        std::cout << "-----------------------------------------------\n";
      };
    
      show("BEFORE ADDING NEW EDGE");
    
      moab::EntityHandle e2;
      mb.create_element(moab::MBEDGE, vertices.data(), 2, e2);
    
      show("AFTER ADDING NEW EDGE");
    
      return 0;
    }
    

    The output is:

    -----------------------------------------------
    BEFORE ADDING NEW EDGE:
    
    cells attached to e3 edge: [3458764513820540929 ]
    
      Vertex ID  X        Y        Z        Adjacencies   
      ---------- -------- -------- -------- -----------...
    (Sequence [1,8] in SequenceData [1,16384])
               1        0        0        0  Edge 1 4  Quad 1
               2        1        0        0  Edge 1 2  Quad 1
               3        1        1        0  Edge 2 3  Quad 1
               4        0        1        0  Edge 3 4  Quad 1
               5      0.5        0        0  Edge 1  Quad 1
               6        1      0.5        0  Edge 2  Quad 1
               7      0.5        1        0  Edge 3  Quad 1
               8        0      0.5        0  Edge 4  Quad 1
         Edge ID Connectivity    Adjacencies
      ---------- --------------- -----------...
    (Sequence [1,4] in SequenceData [1,16384])
               1    1    2    5
               2    2    3    6
               3    3    4    7
               4    4    1    8
         Quad ID Connectivity                             Adjacencies
      ---------- ---------------------------------------- -----------...
    (Sequence [1,1] in SequenceData [1,16384])
               1    1    2    3    4    5    6    7    8
    -----------------------------------------------
    
    
    -----------------------------------------------
    AFTER ADDING NEW EDGE:
    
    cells attached to e3 edge: []
    
      Vertex ID  X        Y        Z        Adjacencies   
      ---------- -------- -------- -------- -----------...
    (Sequence [1,8] in SequenceData [1,16384])
               1        0        0        0  Edge 1 4 16385  Quad 1
               2        1        0        0  Edge 1 2 16385  Quad 1
               3        1        1        0  Edge 2 3  Quad 1
               4        0        1        0  Edge 3 4  Quad 1
               5      0.5        0        0  Edge 1  Quad 1
               6        1      0.5        0  Edge 2  Quad 1
               7      0.5        1        0  Edge 3  Quad 1
               8        0      0.5        0  Edge 4  Quad 1
         Edge ID Connectivity    Adjacencies
      ---------- --------------- -----------...
    (Sequence [1,4] in SequenceData [1,16384])
               1    1    2    5
               2    2    3    6
               3    3    4    7
               4    4    1    8
    (Sequence [16385,16385] in SequenceData [16385,32768])
           16385    1    2     
         Quad ID Connectivity                             Adjacencies
      ---------- ---------------------------------------- -----------...
    (Sequence [1,1] in SequenceData [1,16384])
               1    1    2    3    4    5    6    7    8
    -----------------------------------------------
    

  3. Iulian Grindeanu

    yes, thanks, if that is true, probably for “equivalent” entities, we look only at the corner nodes.
    Also, the ErrorCode MB_MULTIPLE_ENTITIES_FOUND=5 refers in some return codes to this case; multiple entities found on top of each other.

    I propose removing the internal adjacency storage completely, and keep only vertex-based adjacency. I am still trying to explain the use-case / scenarios of why this was implemented in the first case.

    Only @Tim Tautges may offer some insight

    It is not going to happen soon, Vijay is working on a MOABX simplified version, that scraps that stored adjacency. This will be better for MPI+X (GPU systems for example)

  4. olivier jamond reporter

    Okay, thanks for these clarifications. I understand that on the short term we have to live with that “bug”…

    Can you tell me more about MOABX? Do you have some insights about when it will be released?

  5. Vijay M

    I am sorry about the tardy reply. The notifications didn’t come through as expected.

    I am working on a new interface but it is not yet ready for prime-time testing. There is no support for higher-order nodes and many corner cases are not yet tested (though most should work out of the box). I shall let you know when it is ready for testing. If you have a MOAB::Core database in-memory, you should be able to pass that in to generate a MOABX version of the data that is compact and portable (CPU/GPU). I don’t expect to have it public at least for the next 3 months, and merged into MOAB proper before next summer given that I’m strapped for time.

    I will look at the example code and discussions above in more detail before offering my comments/suggestions.

  6. olivier jamond reporter

    Dear moab developers,
    I allow myself to come back to you in order to know if you have been able to take a look at this problem?

    Many thanks!

  7. Iulian Grindeanu

    Hello Olivier, we did not tackle this problem yet
    @Tim Tautges @Vijay M @Patrick Shriwise ; do we have a need for explicit adjacencies ? I would like to remove it
    Or at least deprecate this feature and remove it in the future;
    I still do not get the logic for equivalent entities, and what is their use case

  8. Vijay M

    @olivier jamond I will keep you posted about the new interface after some more testing.

    Have you tried enabling the AHF support in MOAB? It should be faster than the native adjacency tables stored in MOAB, and hopefully does not have some of these quirks. You should be able to configure with --enable-ahf. I would be curious to see if you see similar results there as well.

  9. Log in to comment