In my attempt to create a minimal example to reproduce the error I think I found the cause of the error that I pasted from petsc.
When there are two forms defined for the same pair of function spaces (block) but on different meshes, the sparsity pattern for the “GenericTensor” will be constructed based on only the mesh from the first form. When the other form (integrated over a different mesh) is about to be assembled, dolfin tries to add nonzeros to indices in the petsc matrix not present in the sparsity pattern.
Below is a minimal example that causes that error:
from dolfin import *
# Generate the meshes
square = UnitSquareMesh(8, 8)
# Mark the right boundary
facet_marker = MeshFunction("size_t", square, square.topology().dim()-1, 0)
for f in facets(square):
facet_marker[f] = 1 - DOLFIN_EPS < f.midpoint().x() < 1 + DOLFIN_EPS
right_boundary = MeshView.create(facet_marker, 1)
# Mark the facets of the lower and upper part of that boundary
facet_marker = MeshFunction("size_t", square, square.topology().dim()-1, 0)
for f in facets(square):
facet_marker[f] = ((1 - DOLFIN_EPS < f.midpoint().x() < 1 + DOLFIN_EPS)*
(1 + (0.5 - DOLFIN_EPS < f.midpoint().y())))
upper_right_boundary = MeshView.create(facet_marker, 1)
lower_right_boundary = MeshView.create(facet_marker, 2)
# Initialize function spaces for full domain on the full right boundary
V, V_boundary = [FunctionSpace(mesh, "CG", 1) for mesh in [square, right_boundary]]
W = MixedFunctionSpace(V, V_boundary)
u = TrialFunctions(W)
v = TestFunctions(W)
# Prepare to integrate over only parts of the right boundary
dsU = Measure("dx", domain=upper_right_boundary)
dsL = Measure("dx", domain=lower_right_boundary)
# Form
a = u[0]*v[1]*dsU + u[0]*v[1]*dsL
L = v[0]*dx
sol = Function(W)
assemble_mixed_system(a == L, sol)
If changing the form to, for instance
a = u[0]*v[0]*dsU + u[0]*v[1]*dsL
the assembly works fine. since there is at most 1 form per block.
The block (0, 1) in the matrix to the form in the first example seems to be assembled in two steps. On the line https://bitbucket.org/fenics-project/dolfin/src/946dbd3e268dc20c64778eb5b734941ca5c343e5/dolfin/fem/MixedLinearVariationalSolver.cpp#lines-168:
assemble_mixed(*(As[i*u.size() + j]), *(a[i*u.size() + j][k]), bool(k>0));
Here i = 0, j = 1 and k = 0 for the first form and then k = 1 for the second. This is when it crashes.