-
Notifications
You must be signed in to change notification settings - Fork 41
Mesh representation (for FEM) #131
Comments
I think there needs to be a base mesh data structure without any toppings. This can be defined inside I think there needs to be a minimal "interface" that any mesh type can define and be automatically visualized. So I recommend defining The interface for
The interface for
The Making the interface minimal is important and even more importantly to not expose any visualization internals to the FEM developer to make it more developer-friendly. The interface can be formalized by traits but this may be overkill because it will burden the developer with having to define the traits on their types. I don't see a merit to traits here but correct me if I am wrong. Attributes can/should probably use traits, since they can return numbers, tuples, tensors, be time- and/or space- dependent, etc. So dispatching correctly on all these "super-types"/"traits" is important when visualizing. One point worth highlighting here is that of higher order elements. An |
CC-ing @haampie |
CC-ing @ysimillides |
Some thoughts on the proposals above: Some (imprecise) definitions
DiscussionIn order to elucidate the potential role that the standardized mesh representation could play, it might be useful to consider how it might be used in a finite element program. What do writers of FE programs expect of the mesh entities? An incomplete list of typical actions is:
If the proposed mesh representation only defines the data structure for the mesh, the reason to adopt it in finite element programs is in my opinion not strong enough. Defining an interface to some basic operations on the mesh (such as those above) might be a sufficiently compelling reason to build the FE program around such mesh representation. Especially if there were reasonable default implementations of this interface that would be easy to layer on top and customize. |
Because of the different styles that these can be done in inside the FEM package and the technical FEM knowledge and careful testing they need, I recommend keeping this "standardized mesh" representation to a minimal scope, i.e. for visualization. That is to have a either a set of functions to be defined for your mesh/cell to be visualized by Makie, or to have a basic mesh type visualizable by Makie that can be then made part of a bigger fancier This de-scoping is as much for the benefit of a visualization developer as it is for a FEM developer so each can do their specialized job without knowing much about the other end of the world, only what they need to know. That's my opinion anyways. |
I don't think many people will use the mesh struct directly in their FEM code base, but instead use it as a target for converting to when visualizing. |
I agree with @mohamed82008. While similarities between FEM packages may exist, everyone will have a slightly different focus, and thus structure. From the point of view of Makie/plotting, wouldn't it be better to have a plotting/mesh/trisurf function which takes as an input the node coordinates/connectivity (and values for when plotting solution), and then individual packages can overload this function with their specific FEM structures? Edit : This seems to be what @KristofferC is also suggesting? |
An interesting suggestion which comes to mind from Kristoffer's comment, may or may not be what he meant, is to essentially do the opposite of my first suggestion, that is define the mesh type in GeometryTypes and define the functions needed in the FEM package, e.g. iterators over the cells and nodes of cells, which is really the main mesh-related feature used in JuAFEM for instance. The following are some of the things that might be asked for by a FEM developer:
There may be more things to query, but that's an interesting approach to add to the list. |
I can see this last suggestion kind of working for pure Julia FEM packages since one can entertain the fact that the mesh is owned by GeometryTypes and just ask for what one needs, but perhaps not so much for FEniCS where the mesh is owned by Python/C++ and converting all of it to a GeometryTypes compatible form may be too heavy on the memory, since this mesh would still have to be triangulated, i.e. even more memory usage. It would be nice if triangulation can be made as lazy views, that way memory is not replicated, not sure if that's feasible though in the GL world. |
@mohamed82008 , @KristofferC , @ysimillides : As @mohamed82008 just now commented, and as my discussion in the last paragraph above suggested, it might be possible to define an abstract interface to such a mesh structure: the operations are really common to all finite element programs, as everybody does it in some way (but their own distinct way). Therefore having an interface might be an acceptable compromise: comply with the interface, but your implementation is up to you. For some basic operations it might be possible to supplement the abstract interface with some sample implementations (dispatched on abstract types). I don't find such a mesh-type-definition package very appealing for visualization: I agree with @ysimillides that facilities for conversion of volume-, surface-, wire-, and point-like finite elements to displayable entities might be more appropriate for visualization than an actual mesh data structure definition. So then what should be supported is for instance generation of cut and iso (hyper-)surfaces, subdivision of finite element shapes for the purpose of refining the geometry (for instance to support NURBS and higher-order polynomial finite elements), and so on. |
I think the main questions to answer here are: Should the mesh type be owned by GeometryTypes or the FEM package?
I am not sure which path @PetrKryslUCSD or @KristofferC are suggesting. |
The main compelling reason I can see for adopting even a basic mesh type and building stuff on top of it, is if it provides nice utility functions, e.g. iterators, and it can be visualized. Also it would be nice if it can be GPU-stored or distributed on multiple machines, that way one can ask for the part of the mesh on this machine, or apply a series of GPU-map function on subsets of non-interacting elements, etc. I think this last option assumes we went with the first path in my previous comment, since then Simon can define the mesh structure himself, including all the GPU mapping and coloring stuff. |
The most efficient storage of the mesh might depend a lot on your application. For example, if one does hierarchial refinements of quadrilaterals (and then take care of the hanging nodes) one probably want some multilevel format, where each refinement level of the elements are stored contiguously. While for other types of adaptivity, other storage formats can likely be better. My point is that it feels quite unlikely that there can even be a common "base" format that would be used directly in the fem code. But a common format to act as an entry point to nice visualization (similar as to how you now would export to VTK) is likely more approachable. |
With the exception of mesh refinement which I have no experience in, VTK itself supports multiple base mesh types:
Being able to exploit the memory efficiency and convenience of structured or rectilinear meshes, including the cheap boundary and neighborhood information, is important when iterating over the elements or applying boundary conditions. I may be wrong, but I think any adaptively refined mesh will have to be one layer of abstraction above these base types, so there is nothing to lose by starting somewhere and moving on from there. Yes the main focus here is visualization, I assume this is why we are even talking about this. While the above list does not cover all use cases for mesh types, I think the heterogeneous unstructured mesh type is a pretty convergent type, because of its flexible definition. Essentially nothing stops you from throwing in there heterogeneous, overlapping elements of different dimensions, e.g. some linear lines, quadratic triangles, vertices and cubic hexahedrons. So all the unsupported multi-level specialized mesh types can still be visualized so long as they are converted to a |
I created this issue specifically to discuss how to make this overloading easier ;) Because, if we have a clever interface in GeometryTypes, one possibly doesn't need to overload anything in the FEM packages. There are things that are purely geometric, that don't need to be reinvented in all FEM packages. Another reason I opened this issue is, that now with Tetgen, which I consider as a purely geometric package not specific to FEM, I also need a more refined mesh type in GeometryTypes with nodes + cells and holes etc ;) In the end, I probably just need those interface functions defined: decompose(Point, mesh)::Vector{Point} # the nodes
decompoe(Face{2, Int}, mesh)::Vector{Face{2, Int} # line segments for wireframe view
decompose(Face{3, Int}, mesh)::Vector{Face{3, Int} # triangulated view for surfaces Since tetrahedrons etc are well defined geometric structures, we could have those decompositions into Face{2}/Face{3} implemented in GeometryTypes. |
I think some basic PR that supports Makie would be a good starting point. Then it becomes obvious how to extend it to different types of meshes and elements. I want to contribute but I need a backbone program first. |
This is an interesting discussion. I'm not a Julia user yet (currently use MATLAB and GIBBON) so I do not fully understand all that is suggested here. I just wanted to add that there are many different types of element descriptions. For instance there are 4, 10, and 15 node tetrahedral elements, and 8, 20, 27 node hexahedral elements. The basic 4-node tetrahedron has 3-node triangular faces while the 10-node tetrahedron has 6 node triangular faces. The connectivity defining the element varies from one implementation to another. Therefore also the way one composes faces from the element description. Perhaps you can demand that users convert their element descriptions to face descriptions themselves. This way you avoid issues with differences in element descriptions. For a tet4 element one would create a list of 3-node triangles, for a tet10 description a list of 6-node triangles. In GIBBON I have conversion functions e.g. |
@Kevin-Mattheus-Moerman : The "streaming" idea is attractive. It needs some generalization though. It would be good to stream for instance volume elements with the purpose of extracting an iso surface, or to stream surface elements with the purpose of extracting the boundary. |
I wanted to refactor the mesh type long ago in GeometryTypes, and now that I'm working on propper FEM integration into Makie it becomes even more relevant to rethink the mesh representation.
My current thinking is, that at the core one has a set of nodes (vertices) and a vector of cells (faces) that connect those nodes. This can be represented as
view(nodes, faces)
, since the faces do actually represent a view into those nodes. Like this, going from a e.g. tedrahedron to a visualizable surface mesh is just a matter of changing the face type.So why should this part of the FEM infrastructure live in GeometryTypes and what will be the advantage?
Well, everything graphic related works pretty nicely with GeometryTypes.
I have a
decompose
infrastructure in place, which supports decomposing arbitrary geometries into its components.E.g., this makes it very easy to visualize all kind of wireframes, meshes etc, since I can just do:
Node, that
decompose(Face{3, Int}, polygonmesh)
already works to triangulates meshes with arbitrary faces.So the Makie recipes could just live in GeometryTypes and work across all meshing/fem packages.
This discussion becomes more relevant, since I just made a big step forward in making Tetgen available as a package, so I expect to use advanced meshing a lot more in the future:
JuliaGeometry/TetGen.jl#7
The problem with the use of view as above is, that
node[face] == NTuple{N, Node}
, since one face/cell connects multiple nodes.But in principle, that's most of what we need to represent a mesh. If we want more attributes per node, we can put them into the node type.
I wonder if we should pirate the meaning of view, or just have something like:
We might want to define the node type like this, to contain arbitrary attributes:
The above would work nicely with a trait system!
The beauty is, we won't need to pin down the Node/Vertex type right away, and should just be able to keep using already present structures and slowly converge to one representation.
What does everyon think about this? Ready to move some fem meshing types into GeometryTypes?
Best,
Simon
CC: @KristofferC, @ChrisRackauckas , @louisponet, @Kevin-Mattheus-Moerman, @mohamed82008
The text was updated successfully, but these errors were encountered: