# ElementMeshInterpolation on a BoundaryMesh

It appears as though ElementMeshInterpolation does not play nice with the element meshes produced by BoundaryMesh

<< NDSolveFEM
bmesh = ToBoundaryMesh[Ball[]];
bscalarvals = RandomReal[1, Length[bmesh["Coordinates"]]];
bmeshinterp = ElementMeshInterpolation[{bmesh}, bscalarvals];

(* ElementMeshInterpolation::fememtlq: The quality -1. of the underlying mesh is too low. The quality needs to be larger than 0.. *)


This seems to stem from the fact that, being a surface mesh, bmesh has no volume elements. Is there some way to trick this thing into working or acquire the desired functionality in some other way?

In the meantime I've written something to convert points on the surface mesh to the barycentric coordinates of one of the triangles and interpolate that way, but I wonder if there is a better way.

Following the recent question Interpolation on an unstructured mesh, you should be able to do something like this:

Needs["NDSolveFEM"]
bmesh = ToBoundaryMesh[Ball[]];
mesh = ToElementMesh[bmesh["Coordinates"]];
bscalarvals = RandomReal[1, Length[bmesh["Coordinates"]]];
bmeshinterp = ElementMeshInterpolation[{mesh}, bscalarvals];
SliceContourPlot3D[bmeshinterp[x, y, z],
x^2 + y^2 + z^2 == 1, {x, -1, 1}, {y, -1, 1}, {z, -1, 1}]


# Torus case

In response to @alessandro comment about the approach not working on a torus, the following workflow seems to work.

Needs["NDSolveFEM"]
lhs = ((Sqrt[x^2 + y^2] - 2)/1)^2 + z^2;
ir = ImplicitRegion[lhs <= 1, {x, y, z}];
bnd = 3;
bmesh = ToBoundaryMesh[ir];
mesh = ToElementMesh[bmesh["Coordinates"]];
bscalarvals = RandomReal[1, Length[bmesh["Coordinates"]]];
bmeshinterp = ElementMeshInterpolation[{mesh}, bscalarvals];
SliceContourPlot3D[bmeshinterp[x, y, z],
lhs == 1, {x, -bnd, bnd}, {y, -bnd, bnd}, {z, -bnd, bnd},
PlotRange -> {{-bnd, bnd}, {-bnd, bnd}, {-bnd, bnd}, {0, 1}}]


• That looks like it'll do it! Shame about the needless tetrahedrons, but its no matter. – alessandro Dec 3 '20 at 19:41
• @alessandro You probably could accomplish the same thing without the tetrahedra using UV mapping, but I suspect it would be more complicated. If the memory burden is tolerable, this is a simple approach. – Tim Laska Dec 3 '20 at 19:54
• I considered this, but then you have to be careful about preserving the embedding in 3d space. Seemed like more trouble than it was worth. – alessandro Dec 3 '20 at 21:32
• This doesn't work for surfaces which are not convex. Eg a torus ToElementMesh[MeshCoordinates[DiscretizeRegion[ImplicitRegion[((Sqrt[x^2 + y^2] - 2.0)/1)^2 + z^2 <= 1, {x, y, z}]]]]["Wireframe"]` Not that I particularly expected it would, but I need to figure something out for these surfaces as well. I guess I can switch back to the barycentric coordinate strategy. – alessandro Dec 8 '20 at 14:59
• @alessandro, I added a torus example to the answer. – Tim Laska Dec 8 '20 at 16:37