Entity id when mixing first order and high order entities
Dear moab developpers,
I do not know if this is a bug or the expected behavior, but I got a quite serious problem with the ids of the entities when I try to mix first order and higher order entities. To give a bit of context, in the program I am working on, I use the ids of the entities (which I get using id_from_handle
) as index into type-wise dynamically allocated arrays. For a given moab entity type, I expect that these ids are not larger than the number of entities of this type in the mesh. But when mixing first/higher order entities this does not seems to be verified anymore. The following simple snippet illustrates that:
#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.},
{2., 0., 0.},
{2., 2., 0.},
{0., 2., 0.},
{1., 0., 0.},
{2., 1., 0.},
{1., 2., 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 q8;
mb.create_element(moab::MBQUAD, vertices.data(), 8, q8);
std::vector<moab::EntityHandle> adj;
mb.get_adjacencies(&q8, 1, 1, true, adj);
moab::EntityHandle s3;
mb.create_element(moab::MBEDGE, std::vector{vertices[0], vertices[1], vertices[4]}.data(), 3, s3);
moab::EntityHandle s2;
mb.create_element(moab::MBEDGE, std::vector{vertices[0], vertices[1]}.data(), 2, s2);
moab::EntityHandle q4;
mb.create_element(moab::MBQUAD, std::vector{vertices[0], vertices[1], vertices[2], vertices[3]}.data(), 4, q4);
std::cout << " >> node ids" << std::endl;
std::vector<moab::EntityHandle> nodes;
mb.get_entities_by_dimension(0, 0, nodes);
for (const auto &node: nodes) {
std::cout << " "
<< mb.id_from_handle(node) << " " << std::endl;
}
std::cout << " >> edges ids" << std::endl;
std::vector<moab::EntityHandle> edges;
mb.get_entities_by_dimension(0, 1, edges);
for (const auto &edge: edges) {
std::cout << " "
<< mb.id_from_handle(edge) << " " << std::endl;
}
std::cout << " >> cells ids local/global" << std::endl;
std::vector<moab::EntityHandle> cells;
mb.get_entities_by_dimension(0, 2, cells);
for (const auto &cell: cells) {
std::cout << " "
<< mb.id_from_handle(cell) << " " << std::endl;
}
return 0;
}
When executing this, I get:
>> node ids
1
2
3
4
5
6
7
8
>> edges ids
1
2
3
4
5
524289
>> cells ids local/global
1
524289
Although I have 6 edges and 2 quads in my mesh, I get these ids which are 542289…
Is this the normal behavior? If yes, would there be a trick to have that expectation that the ids are not bigger than the number of entities for a given type (here 2 for the MBQUAD and 6 for the MBEDGE)?
Thanks
Comments (2)
-
-
reporter Thanks for your answer.
Just to be perfectly sure that I understood what you wrote: can you confirm that from moab 5.4, the maximum difference between the ids of the entities of a given moab type, and the number of entities of this type is 4092? If this is right, it’s ok for me as for big models overallocation of 4092 items is not that bad (but 542289 would start to be significant…).
- Log in to comment
This is expected behavior
There are 2 different sequences for your edge entity handles, and 2 sequences for quads; they differ by number of nodes in the sequence
A sequence has a default size, that in moab 5.3 was bigger (in moab 5.4 is about 4092). If you run this code in moab 5.4 the numbers will be smaller, but still “discontiguous”
When you use “create_element” with a different connectivity size, you will have a new sequence; the entity handle id will be from the “next” free sequence available;
If you want an index, you will have to maintain it yourself
for example:
std::map<moab::EntityHandle, int> ehmap;
ehmap[eh] = index
Or put all edges in a range, and use index method
moab::Range edges;
moab::EntityHandle edge;
int index=edges.index(edge) // (this will return index, from 0, up to Range::size()-1, or -1 if the 'edge' in not in the Range edges)