I think I've found the problem, but I haven't fixed it yet...
The sync() function uses the Elem::build_side() method to construct
an element which is later placed into the boundary mesh. The
problem is that the build_side() method doesn't return an actual
Elem, but a proxy which forwards all subsequent calls to its
"parent" element, including resetting the node pointers, which
messes up the original mesh and eventually results in the seg-fault
The build_side() optimization is typically a very good thing: it
does not dynamically create new storage for an element when you
don't really need it. Unfortunately in this case we DO need it,
but there is no Elem::expensive_build_side() (there used to be
before we optimized it out with the current version.)
Elem::side() won't work either: it returns a "minimal" side i.e.
a Quad4/8/9 all return an Edge2. I noticed that all of the build_side()
functions still have the old code, but it is commented out. One
fix would be to add an extra argument to build_side which by
default would return the lightweight proxy, but could be used to
get a non-proxy, full-ordered side instead.
What do the developers think?
Martin L,b|(Bthi writes:
> Back to the BoundaryMesh problems again. Before I embark on trying to
> fix the bug described below, I wonder what the state is in the
> discussion. Ben once wrote that BoundaryMesh has to go (and I totally
> agree), but we need a replacement.
> Specifically I would like to create a mesh of all boundary elements
> (2D for a 3D mesh), and solve an equation system on that mesh, that
> takes data from the 3D problem solution vector. So obviously one needs
> to share at least node ids, or references to the nodes. What would be
> the best approach now, and in the future?
> The bug I talked about above is easily reproduced:
> Add the following lines to any example (I used ex3). Libmesh segfaults
> on the second system.solve().
> for (unsigned int i=0; i<3; i++)
> BoundaryMesh boundary_mesh (mesh.mesh_dimension()-1);
> mesh.boundary_info->sync(boundary_mesh, false);
> Thanks, Martin