Lagrangian movement: no realized displacement

Hi mmg community,

I have been running the Lagrangian movement mode with constant mesh connectivity (-lag 0) to deform a closed 2D surface within a 3D mesh.
When the surface is smooth then it works fine.
However I have two test cases where the movement is not being processed.

//The reference boundary is set to 1 in src/common/
#define MMG5_DISPREF 1
// The maximum number of iterations is set to 100 in src/mmg3d/mmg3d3.c
# The command I used to run the test cases
./mmg3d_O3 -in mesh_init_bot_0.1  -out mesh_init_bot_0.1.o.mesh -sol movement.sol -lag 0

I understand that the movement cannot always be processed at 100%, which is fine.
Yet I am not sure to see in which case no movement at all can be processed since:

  • we keep a constant mesh connectivity, so there cannot be an intersection with the bounding box or any other boundary
  • the mesh seems coarse enough so that the default 20 layers element submesh can handle the movement (or at least part of it)

Is there something else that I have missed?

Thanks for your help,

Hello Gaëtan,

I will split my answer in two different messages. First, for the test case 1:

test case 1

Mmg doesn’t move anything due to the way it manages the boundaries (so the triangles). For Mmg, a triangle is a boundary entity, wich means that we have a triangle along a tetra face if and only if:

  • the tetra doesn’t have a neighbour through this face (external face);
  • the neighbour through the face has a different reference (color) than the current tetra;

To obtain a mesh that matches with this vision, Mmg begins by a step where the input mesh is analyzed and where the triangles entities are reconstructed:

  • if the user provide a “Mmg” boundary triangle, it is keeped with it’s reference;
  • if the user provide a triangle at the interface of 2 tetra with the same reference, it is deleted;
  • if the user doesn’t provide a triangle between 2 tetra with different references, we create a new triangle with the lower reference;

As you use tetgen to create your mesh, the input mesh contains all the tetra faces (boundaries in the sense of Mmg or not) and Mmg warns you that it deletes lot of them:
## Warning: MMG5_chkBdryTria: 1181612 extra boundaries provided. Ignored.

Moreover, in the test case 1, the ellipse volume has the same color (reference) than the cube volume while for the 2 other test cases, the colors are different (see the pictures, the first is the mesh of the test case 0, the second is the mesh of the test case 1). Thus, in the test case 1, the triangles at the ellipse surface are deleted and the only triangles that are keeped are along the cube boundaries. As the displacement over the cube boundaries is 0 everywhere, Mmg consider that it has realized the entire prescribed displacement.

A last remark : there is some other non-compatibilities between Mmg and the output of tetgen:

  • it contains all the edges of the mesh (or at least all the edges over the mesh boundaries) while for Mmg a provided edge is a geometric entity for wich the tangent and normals must be preserved (in a certain sense). Moreover, the intersection between 3 edges is seen as a very special point by Mmg and this point can’t be modified. As consequences, if you authorize the connectivity modifications, you will have very poor results due to this edges;
  • all boundary points are marked as corners while for Mmg a corner is a geometric corner (a point where the underlying geometry to the boundary discretization is C0 only). Again, Mmg can’t modified corners without degrading the surface reconstruction.
  • there is no way for Mmg to detect that the .mesh file comes from tetgen so I can’t treat this for you and in general, it is better to keep only the Vertices and Tetrahedra fields and to remove all the other fields from the .mesh file generated by tetgen.

I will try to answer for the test case 2 this afternoon.

Best regards,


Hi again,

Test case 2

In this case, nothing move due to the detection of intersections even for a very small portion of the prescribed displacement:

  • Mmg apply the same part of displacement to the entire mesh (each node is moved from c*d with c a constant value over the mesh and d the displacment prescribed at the node) and if 1 node can’t be moved, nothing is moved;
  • In your case, you have a nearly flat tetrahedron (tetra 21647) : if you try to move one of the vertex, even for a little, you obtain a negative volume. It is illustrated on the picture below:
    • the left and middle pictures despict your initial tetra (different views). The volume of the tetra is of 2.500581E-04.
    • the right picture shows the final tetra (same view than the left image). If I apply the entire prescribed displacement at nodes, in this last case, I end with a volume of -5.121889E+00).

I try to improve your input mesh quality using Mmg (without modifying the boundaries and with respect to the length of the input edges: -nosurf -optim) but as the tetra 21647 has 2 boundary faces, Mmg has not enough degrees of freedom to improve it, sorry.

Remark : I think that the movement.sol file miss 1 data (you specify 97110 data but give only 97109 values). I fill it by adding a 0 displacement for the last node.



Thank you for the thorough response!

Test case 1

This indeed explains why there is no displacement for a boundary defined between tetra with the same reference.

Test case 2

I guess one way I could overcome the issue is by ignoring the movement for the intersection cases but still displace the rest of the nodes? This is to set d to zero when an intersection is detected.
Also how is c defined? Is this related to the Computation of the largest valid motion along the velocity field step in the dichotomy loop?

Kind regards,


yes, the coefficient c is computed by dichotomy (Computation of the largest valid motion along the velocity field).

I have made some small modifications in the code:

  • If we detect at the first iteration that we can’t move anything, we now exit the loop instead of continuing the iterations;
  • with a verbosity of at least 2 (-v2), if any motion can’t be performed, we print out the number of intersecting tetra (in the last attempt of displacement) and the list of this tetra.



Great, thanks!
This will definitely be useful for debugging the inputs.