On 1/13/21 12:32 PM, Konrad Simon wrote:


I have a quick question: On complicated meshes some faces can have a non-standard orientation or they can be rotated against the neighboring face. This causes inconsistencies for some vector elements.

In principle this potentially causes inconsistencies for FE_Q elements as well (for all dofs located at vertices, lines and faces). But that is being taken care of in the library, so everything seems fine.

In order to understand the issue better for other elements: where in the library is this being taken care of? I have difficulties to find that.

Remark: I found a table in (fe.h/fe.cc) that derived elements need to implement that takes care of local dof permutations on quads (not full faces and hence not line dofs or vertex dofs). Now, lines can have different orientations but lines also permute within a cell upon face orientation/rotation changes.

Can anyone point me to the place in Deal.II where this is being taken care of for FE_Q?

Konrad -- my apologies not only for not getting to this question quicker, but in fact for not helping you along over the past few months. I saw that you are working on this, but it's been a very long time since I understood these issues sufficiently well to help out and I haven't had the time to really read up on it again in enough detail to be useful. I do know that it's a topic for which we, collectively, have probably lost our expertise and that there is likely nobody else who knows it well either. You might be the expert on this at the moment.

Fundamentally, the place to look is to search through the finite element classes where they ask for face and line orientations. It is possible that you don't actually have to do much there: Finite element classes generally work in the local (cell) coordinate system, where you enumerate shape functions as 0...dofs_per_cell. So when, for example, you compute the local matrix, it really is local. The interesting part happens when you translate what *global* degrees of freedom correspond to the local ones, i.e., when you call cell->get_dof_indices() (==DoFCellAccessor::get_dof_indices). This is where on every cell has to collect which DoFs live on it, and that has to take into account the orientations of lines and faces come into play. The cell DoF indices are cached, but you can see how this works in dof_accessor.templates.h, starting in line 902 using the process_dof_indices() functions.

What this means is that if you have two cells that disagree about the relative orientation of their shared face, they when you call cell->get_dof_indices() on these two cells, you'd end up with a different ordering of the DoFs on the face. My usual approach to check this would be to create a mesh with two cells so that one has a non-standard face orientation, assign a Q3 element to the DoFHandler, and check that that is really what happens. (I generally turn these little programs into tests for the test suite, just so that what I just verified to be correct -- or not! -- is actually checked automatically in the future. I would very much love to see you submit such tests as well!)

So this is the process for FE_Q, where there is really not very much to do, or in fact for all interpolatory elements. The situation becomes a bit more difficult for things such as the Nedelec element (also the Raviart-Thomas one) where the shape functions are tangential to the edge. Let's say you have the lowest order Nedelec element. Then there is just one DoF on each edge, and both adjacent cells agree about this. But they also have to agree *which direction the vector-valued shape function should point to*, and that's trickier. I can't remember how we do this (or whether we actually do this at all). I *think* that the RT element gets this right in 2d, but I don't remember about the 3d case. Again, it would probably be quite helpful to write little programs and turn them into tests.

I know or strongly suspect that there are bugs for RT and Nedelec elements on meshes where faces have non-standard orientation. I've been thinking for years how I would go about debugging this, but I've never had the time to actually do it. But I'll share what I think would be the tools to do this:

1/ Creating meshes with non-standard orientations: You can feed Triangulation::create_triangulation() directly so that the faces have non-standard orientations with regard to each other. (See step-14 for how to call this function.) In 2d, this would work as follows: Think of a mesh like this:

  3---4---5
  |   |   |
  0---1---2

You'd describe the two cells via their vertex indices as
  0 1 3 4
  1 2 4 5
but if you want a mismatched edge orientation, you'd just use
  0 1 3 4  (thinks the edge is 1->4)
  5 4 2 1  (thinks the edge is 4->1)
or any other rotation. A good test would probably just try all 2x4 possible rotations of both cells.

2/ How do you check whether things are right or not? There are many aspects, but one I've recently thought would be useful to try out is FEInterfaceValues. Try this: assign a DoFHandler with a continuous but possibly high-order element with multiple DoFs per edge. Create a solution vector and give its elements random elements. This should correspond to some finite element field, and because it is associated with a continuous FE, the jump across the common edge should be zero.

So create an FEInterfaceValues object and check that indeed the jump of the solution (or, more simply, of each shape function) at every quadrature point along that face is really zero. If it is not, there's a bug somewhere.

3a/ For FE_RaviartThomas, the jump itself doesn't have to be zero, but the normal component has to be. That's also easy to check in the same way as above: Use FEInterfaceValues, compute the jump in shape functions or the solution, compute the dot product with the normal to the face, and check that it's zero. If it isn't, there's a bug.

3b/ For FE_Nedelec, it's the tangential component of course.

4/ Repeat these steps for all 2x4 possible rotations of the two cells. In 3d, there are even more one can and should try. Little test programs would just loop over all possible rotations -- I think that GeometryInfo has ways to rotate cells, though I'm not entirely sure.

5/ You can also output the solution that corresponds to the solution vector as chosen above, and visually inspect whether what you get is continuous/has a continuous normal/tangential component.


My best guess is that with such small test programs, you'd uncover cases that don't work and that could, because they don't involve solving whole problems or more complicated set ups, be easier to debug and/or fix. Everything that turns out to work as expected should then be put into the test suite as soon as you've verified that it works -- we accept small additions to the test suite pretty regularly, so feel free to open lots of pull requests in this regard.

As mentioned above, regrettably, we've lost collective knowledge about these issues over the years, and that translates into long response times :-( I'm sorry you get caught up in this. I'd love to have fixed this long ago, and would have loved to help you more with it as well, but time availability is not always on my side :-((

Best
 Wolfgang

--
------------------------------------------------------------------------
Wolfgang Bangerth          email:                 bange...@colostate.edu
                           www: http://www.math.colostate.edu/~bangerth/

--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see 
https://groups.google.com/d/forum/dealii?hl=en
--- You received this message because you are subscribed to the Google Groups "deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to dealii+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/dealii/c0c60681-4e4f-f4e3-c4ac-6e6c8978e7f0%40colostate.edu.

Reply via email to