# Meshing Accuracy in 3d

The Element Mesh Generation tutorial describes how good mesh accuracy is achieved through adjusting boundary nodes so they match the region boundary. This is illustrated with this example:

mesh2d = ToElementMesh[Disk[]];
\[Pi] - Total@First@mesh2d["MeshElementMeasure"]
2.00118*10^-6


When I try the 3d equivalent of this, I get a much bigger error:

mesh3d = ToElementMesh[Sphere[]];
4/3 \[Pi] - Total@First@mesh3d["MeshElementMeasure"]
0.0213137


I suspect this node adjusting process works differently in 3d. Is there a way to improve the accuracy of 3d meshes without requiring a huge number of elements?

In 3D the boundary improvement is much harder than in 2D for this reason it is off by default in 3D. You can turn it on with

mesh3d = ToElementMesh[Ball[], "ImproveBoundaryPosition" -> True];
4/3 \[Pi] - Total@First@mesh3d["MeshElementMeasure"]

0.0000975943


When it's off I get 0.0600351. Should you get messages that the element quality is below zero then the movement of the boundary nodes mixed the mesh structure up. One of these days I'd need to write a better code for the 3D boundary improvement.

For a Sphere you get a better result with:

bmesh = ToBoundaryMesh[Sphere[]];
bmesh["MeshOrder"]
1

Area[Sphere[]] - NIntegrate[1, Element[{x, y, z}, bmesh]]
0.035370648951490224


Versus:

bmesh = ToBoundaryMesh[Sphere[], "MeshOrder" -> 2];
bmesh["MeshOrder"]
2

Area[Sphere[]] - NIntegrate[1, Element[{x, y, z}, bmesh]]
0.00012678984229808066


(Note there is no "BoundaryElementMeasure"). "ImproveBoundaryPosition" does not seem to have an effect here. I can quite say off hand why that is.

In some cases Method 3 (attaching a symbolic region to a numeric region for improving accuracy) can be useful too.

• Thanks @user21. When I try using the "ImproveBoundaryPosition" -> True option on a Sphere (instead of a Ball) I don't see any improvement in accuracy. Is that because a Sphere is a shell rather than a solid body? Jul 8, 2021 at 0:56
• @JackMcInerney, see update. Jul 8, 2021 at 4:52