-
-
Notifications
You must be signed in to change notification settings - Fork 402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement regions #175
Comments
Reading about Exodus boundary conditions, I see that besides what it calls 'element blocks', corresponding to the above, it also has 'nodesets' and 'sidesets', the last two being useful for boundary and initial conditions, and 'sides' being sides of elements. |
Exodus Element Blocks are stricter than Gmsh Physical Regions; whereas the latter encode only the continuous concept of subdomain, the former mixes in the discrete notion of type of element.
In a 'quad-dominant' mesh of a surface, this would necessitate two blocks, for the triangles and quadrilaterals. I can see computational advantages to this: the connectivity would be described by a rectangular matrix rather than a list. But it also seems like an admixture of concerns if one just wants to specify that a subdomain is of one material. |
What would the computational advantage be of having the elemental group
data as matrix instead of a list? For one, a list (or list of lists) would
be much sparser, plus this information is already provided by meshio in the
form of dictionaries with list/array values, which I think is now provided
by the 'cells' and 'cell_data' objects.
…On Fri, Dec 22, 2017, 21:17 Geordie McBain ***@***.***> wrote:
Exodus Element Blocks are stricter than Gmsh Physical Regions; whereas the
latter encode only the continuous concept of subdomain, the former mixes in
the discrete notion of type of element.
Element Blocks (also referred to as simply, Blocks) are a logical grouping
of elements all having the same basic geometry and number of nodes. All
elements within an Element Block are required to have the same element
type. (ibid)
In a 'quad-dominant' mesh of a surface, this would necessitate two blocks,
for the triangles and quadrilaterals. I can see computational advantages to
this: the connectivity would be described by a rectangular matrix rather
than a list. But it also seems like an admixture of concerns if one just
wants to specify that a subdomain is of one material.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#175 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AMTd7KePPmdbBvud0QNXM3SQ00aY8aZ8ks5tDA5wgaJpZM4RJrl->
.
|
Hmm. I was trying to second-guess why Exodus insisted on one type of element per block. |
As to the relation between this and what's currently in the meshio cell_data and field_data, I think they're like inverses, as discussed in the final comments yesterday on #169. |
I also think this will be the reason. This is by the way also what comes out of a meshio read: The cells a segregated by their element type so the connectivity data is just one big n-by-k array, where n is the number of cells and k the number of nodes per cell. This makes many things really convenient. |
Anyhow, on to regions. Any opinion yet on how to implement them? The possibilities I see right now are
I generally like the second approach better because it allows to naturally associate a string with the regions and permits cells to be a member of an arbitrary number of regions (also none at all). Perhaps Exodus-style point sets could also be incorporated in the this approach with the |
Your last one is promising, however there is something missing. In some formats (e.g. Gmsh), the region names are mapped to an integer tag. Maybe regions = {
'boundary': (int_tag_1, {'triangle': [0, ...]}),
'copper': (int_tag_2, {'triangle': [0, ...]}),
} Also, maybe the PS: At this point I'm wondering whether PS: What we are trying to achieve made me remember this joke https://xkcd.com/927/. |
Yeah, we should definitely allow integer tags. Also, parallel to regions = {'triangle': {'boundary': [0, ...], 8: [0, ...]}} @dalcinl Do you know if it's guaranteed in gmsh that physical tags and geometrical tags are always different? |
Also, good idea about the container type. This would allow us to add more data without breaking the API (as we have to do now). |
In gmsh, physical tags and geometrical tags are orthogonal concepts, they can certainly be the same. You can have let say a boundary face with physical tag 1 that comes from a geometrical entity with tag 1. PS: So is the |
Also, eventually you need something like a |
All good suggestions. This should probably be made a separate issue. About the different gmsh tags: Tuples as keys is certainly possible, but seems a bit wasteful. The fact that there are multiple different tag types appears to be very specific to gmsh. A more natural approach seems to be to use 'physical{}'.format(k)
'geometrical{}'.format(k) as keys. Optionally, the physical list could be replaced by their respective entris in |
Well, to add complications, gmsh physical regions can have names, I submitted a PR some time ago adding support for them. IMHO, Gmsh's geometrical tags are rather useless in a mesh, they are sort of references to the tags of geometrical entities in the |
No problem, I got this covered. I've now added gmsh region reading in this branch; will see about writing now. Feedback welcome. |
Yes, so at the moment I have something like this in my unpublished finite-element module based on meshio and pygmsh. (At least, I hadn't heard of "container class" before but I think I get the idea.) class Mesh(object):
dimension = NotImplemented
def __init__(self, points, cells,
point_data=None, cell_data=None, field_data=None):
self.points, self.cells = points, cells
self.point_data = {} if point_data is None else point_data
self.cell_data = {} if cell_data is None else cell_data
self.field_data = {} if field_data is None else field_data
@classmethod
def from_geo(cls, geometry: Geometry, *args, **kwargs):
return cls(*generate_mesh(geometry, dim=cls.dimension, *args, **kwargs)) Is that what you meant? If meshio had such a class, I would use it or subclass it, I think, rather than catching the multiple values returned by read (via generate_mesh) in my classmethod constructor. |
Let's not mix discussions. I've just opened an issue for the container discussion at #198. |
Alright, the regions now kind of work in the branch, but I'm not sure if I'm a hundred percent happy with it. The design is now such that the reader will return something like regions = {
'triangle': {
'physical-1-copper': [...],
'physical-5-iron': [...],
'geometrical-8': [...],
}} from a gmsh mesh. The lists are indices in the cell array. When writing, you supply such an object to the writer, and tags and physical names are extracted from the keys. While I think the above format is most useful for applications, I cannot see a mesh format that actually implements tags like that. (Please correct me if I'm wrong.) Even gmsh demands one and only one tag to be present for each cell in both physical and geometrical groups. I don't see much difference to a cell data array with int dtype. This is also how you're supposed to handle subdomains in VTK. I'm wondering now if we should implement pseudo-regions simply as cell data arrays with a specific name, e.g., |
I'm not so keen on packing metadata into strings. @dalcinl proposed more structured tags, which generally seems more Pythonic. Another idea is to store the metadata hierarchically. What's in master at the moment is hierarchical, where in |
Well, Gmsh want's to store a string and an integer with each region. I guess that's what you get when you settle for a format like that, but it isn't pretty. I'm not a fan of making a tuple a key in dictionary, but, as suggested above, what we could do is simply store two separate things:
I think that's more or less what we had done earlier anyways. Advantages of this:
Disadvantages:
What do you think? |
@gdmcbain By |
@dalcinl Remember we're discussing regions here. If it's about the a container class, please move you're contributions to the appropriate issue. |
Yes, I know. Should be regions (or part of the info about them) be considered metadata that is too much format-specific? |
First we have to decide how to do regions. If we decide to just wrap them as part of cell data (see suggestion above), we hardly need any meta data. |
Perhaps If you still want to encode regions with cell data, that's fine, but we need to devise a mechanism to distinguish integral values (for gmsh regions, aka physical/elementary tags) from scalar/vector data (for gmsh |
Generally you're right here. The thing is that Gmsh doesn't make use of the freedom: Both physical and geometrical data are simply integer arrays over cells, just like
That should be easy: The two region values of gmsh are called |
What's in a name? :-) What would happen if you read from a VTK file with a cell data entry named Anyway, you seem to suggest going back to previous approach where |
Thanks for clarifications. This is all sounding O. K. to me as far as it goes, but… I've just realized why I hadn't been bitten by the change as @dalcinl was this time, whereas I had been back in #169. I don't ask meshio to write .msh files, only read them, and that implicitly by using So this isn't really about what I thought it was when this issue was launched in December; i.e. whether the data structure for the regions should be inverted. This sounds more like #197, but I see that the discussion from there was moved back here. To return it for the moment to the original question of which way the looking-up of regions should go, I see that Gmsh in the MSH format in the |
@gdmcbain Thanks for your comment! If I would sign all of this I could. For my own applications, I would rather need Okay, I think this is how it's gonna go:
|
Alright, thanks everyone for hanging in there. I've just published 1.11.7 with the proposed fix. |
What I'm thinking more generally, trying to not to be Gmsh-centric, is that some input or output formats will store regions as element -> region and some as region -> element. (I'm not imagining any other possibilities than these two, though I did try to.) It's true that we don't know of any mesh formats that support region -> element-index with elements being allowed to belong to more than one region, Exodus II with its Element Blocks does more work in the direction of region -> element than element -> region. Another reference for the format (especially ‘Anatomy of an Exodus II file’ in §3):
But anyway, not tying meshio too closely to any existing format, I wondered about whether the format-neutral data-structure that meshio builds and populates when called to read and uses when called to write, what if it had both possibilities?
Then in
Then in
I imagine not usually having both |
I was disappointed to learn by way of the above that
but indeed, from Gmsh's MSH ASCII file format:
That's quite a shortcoming. I wondered what happens if two physical entities are defined that overlap. I tried this with:
and found that Gmsh makes two lots of elements over 0 < x < 1.
The first two elements here have the same endpoints. I suppose in practice (and I'm very surprised that I haven't hit this yet in my work) that what one would have to do is define three separate physical entities for the intersection and two relative complements and then use the union of the intersection and one of the two relative complements. Not nice. |
Thanks Geordie for the concise write-up!
Yeah that'd be nice to have. I believe it'd make sense to wait for an actual use case of this and then design meshio around that. Having
Very interesting discovery! I'm surprised that not even Gmsh itself makes proper use of its tags. That makes me wonder why they didn't use |
This was touched on by C. Geuzaine (2018-09-06) as one of the motivations for the introduction of MSH4 #280.
These points might guide #289. |
Some data formats have the concept of regions/submeshes/domains, e.g., gmsh and Exodus. Think about how to best integrate this into meshio.
The text was updated successfully, but these errors were encountered: