This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

How does FEniCS handle integration over subdomains that do not align with cell boundaries?

+4 votes

Say $\Omega$ is the domain and V a FEM space over $\Omega$. Say $\Omega_i$ is a subdomain and f_i is a function with support in $\Omega_i$, i.e. f is zero outside $\Omega_i$.

I want to assemble the form that is related to the functional $f(v) := \int_\Omega f\cdot v dx$ on V. So, let v be a TrialFunction(V).

If I simply compute inner(f, v)*dx, the computed integrals may be a poor approximation since the quadrature undersamples f. This happens in particular at the boundary of $\Omega_i$ if it does not align with the cell boundaries of V.

I was thinking of defining $\Omega_i$ as a subdomain with the measure dx(1) and compute inner(f, v)*dx(1).

Thus, my question is: How does Fenics handle these cases, where the boundary of the domain of integration does not aligh with the actual cell boundaries?

Or is there a better way to avoid the undersampling described above?

EDIT
As Jan Blechta has pointed out, integration in FEniCS only considers complete cells. The following script gives an example on the interval $\Omega : = [0,1]$ divided into 5 segments, with the FEM space Y, and a function ffunc that is $1$ on $(0.1, 0.3)$ and zero elsewhere. Say '1' is the constant mesh function in Y that is always one.
enter image description here
If one defines the subdomain funcdom as the interval $(0.1, 0.3)$ with the measure dx(1), one obtains that inner('1', ffunc)*dx(1) is $0$. Probably because, the subdomain does not share a cell with Y.

The integral over the whole domain gives the correct value 0.2, probably, because FEniCS (mis)interpretes the function as the triangle marked in red.

import dolfin

class LocFun(dolfin.Expression):
    """ a locally defined constant function"""
    def __init__(self, xmin, xmax, fvalue=1):
        self.xmin = xmin
        self.xmax = xmax
        self.fvalue = fvalue
    def eval(self, value, x):
        value[:] = self.fvalue if self.xmin < x[0] < self.xmax else 0

class LocFuncDom(dolfin.SubDomain):
    """ domain of definition as subdomain """
    def __init__(self, xmin, xmax):
        dolfin.SubDomain.__init__(self)
        self.xmin, self.xmax = xmin, xmax
    def inside(self, x, on_boundary):
        return (dolfin.between(x[0], (self.xmin, self.xmax)))

# extension of the domain where ffunc is not 0
smin, smax = 0.1, 0.3

mesh = dolfin.IntervalMesh(5, 0, 1)
# dolfin.plot(mesh)

Y = dolfin.FunctionSpace(mesh, 'CG', 1)

y = dolfin.Expression('1')
y = dolfin.interpolate(y, Y)
# dolfin.plot(y)

domains = dolfin.CellFunction('uint', Y.mesh())
domains.set_all(0)

# the support of ffunc as subdomain
ffunc = LocFun(smin, smax)
funcdom = LocFuncDom(smin, smax)
funcdom.mark(domains, 1)

dx = dolfin.Measure('dx')[domains]

# dolfin.plot(ffunc, mesh)
# dolfin.interactive(True)

# ffunc integrated over the whole domain
y1 = dolfin.inner(y, ffunc) * dolfin.dx
# ffunc integrated on over its support
y2 = dolfin.inner(y, ffunc) * dx(1)

print dolfin.assemble(y1), dolfin.assemble(y2)
asked Nov 11, 2013 by Jan FEniCS User (8,290 points)
edited Nov 12, 2013 by Jan

FEniCS (mis)interpretes the function as the triangle marked in red

FEniCS does not misinterpret it. It

  • considers ffunc of polynomial degree 1 because you did not set any (note that FEniCS has no way to estimate polynomial degree of DOLFIN expression (either compiled and python-subclassed) in comparison to UFL constructs)

  • finds that Function y is of polynomial degree 1

  • realizes that the integrand inner(y, ffunc) is of polynomial degree 2

  • uses quadrature of degree 2, i.e. reference points$=\pm\sqrt{3}/3$, weights$=1$

which explains the result.

EDIT: This explanation is not correct. See follow-up. Basically it misses interpolation of expression to specified element (default = Lagrange) with specified degree (default = 1) before actual quadrature is performed.

Thank you for pointing this out. I should say, that in this case, FEniCS returns the right value of the integral because of good coincidence. In general, however, one cannot expect the quadrature rules to capture jumps in the function inside a cell.

Yeah, but one can expect good approximation if a quadrature degree is appropriately chosen by a user.

1 Answer

+1 vote
 
Best answer

How does Fenics handle these cases, where the boundary of the domain of integration does not aligh with the actual cell boundaries?

FEniCS does not handle boundary of the domain of integration non-matching with cells. For volumetric integrals there is only cell assembler in DOLFIN computing an integrals over cells. Moreover UFL does not allow to specify volumetric integrals on any other object than a cell.

The exception is represented by pum-compiler/pum-dolfin libraries in a framework of PUM/XFEM methods but these are now deprecated.

If you thought that some your DOLFIN code should compute this kind of integrals then you're probably wrong. Can you post short example?

answered Nov 11, 2013 by Jan Blechta FEniCS Expert (51,420 points)
selected Nov 12, 2013 by Jan

Unfortunately, you seem right. I have added an example to my question.

...