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

Using non-integral in variational formulation

+1 vote

Hi all,

I am currently trying to solve a PDE problem with the variational form:

$$ \int \nabla u \cdot \nabla v \, dx + \sum_{k=0}^{m-1} \left( \int_{e_k} (u-U_k)(v-V_k) \right) = \sum_{k=0}^{m-1} I_k V_k ,$$

where $I_k$ is some defined constant and $e_k$ is some part of the boundary. My problem is, that I am not able to write the right-hand-side of the above form for it to work. If I do the following:

L = sum([I[i]*V[i] for i in range(m)]) 

b = assemble(L)

I get an error in the assembling. V is here defined as

Rm = VectorFunctionSpace(mesh, "R", 0, m)
V = Testfunction(Rm)

Is it at all possible to create a right-hand side as a sum like above, or do I need to compute it as an integral, and then divide by the length of that integral?

asked Sep 23, 2015 by Jeppe FEniCS Novice (190 points)

2 Answers

0 votes

You might use an expression term:

class SumExpression(Expression):
   def eval(self, value, x):
      value[0] = sum([I[i]*V[i]] for i in range (m))
L = SumExpression()

But i am not sure if u can use sum() inside an expression. You might need to define it yourself in a loop.
However, I dont understand how you get a testfunction outside of an integral because I thought the variational/weak form means first multiplying everything with a testfunction and then integrating it over the space.

answered Sep 23, 2015 by MaxMeier FEniCS Novice (850 points)
+1 vote

It will work if you make L an integral. For example,

c = Constant(1.0 / assemble(1.0 * dx(mesh)))
L = sum([c * I[i] * V[i] * dx(mesh) for i in xrange(m)])

If I is a function in Rm, you can instead write

L = c * inner(I, V) * dx

EDIT: I see you have already suggested this solution in your question.
You can avoid the integral formulation, but it is a bit involved since Rm is part of a MixedFunctionSpace:

W = MixedFunctionSpace([V, Rm])
Rm_dofs = W.sub(0).dofmap().dofs()

I = numpy.array([...])

b = Function(W).vector()
b[Rm_dofs] = I

You can then solve with b as right hand side.

answered Sep 23, 2015 by Magne Nordaas FEniCS Expert (13,820 points)
edited Sep 23, 2015 by Magne Nordaas
Using non-integral in variational formulation with dg spaces
...