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

How to solve coupled initial value problem with multiple dofs?

+1 vote

Dear all,
Firstly, I must say FEniCS is really an awesome software. Thanks the developer!!!
I'm using the new version FEniCS, but there are few tutorials about the newest version. Somethings, especially for the coupled initial value problems with multiple dofs for each node.
I see the tutorial on Github for the reaction system(which will deal with multiple dofs, but that doesn't help me)
For example, for some simple diffusion problem coupled with poisson equation.
Let's consider that there are three species,$c_{1}$,$c_{2}$ and $c_{3}$. They are coupled with a potential $\phi$
The governing equations for these four dofs(c1,c2,c3,phi) are list as below:
$\frac{\partial c_{1}}{\partial t}=\nabla\cdot(D_{1}\nabla c_{1}+D_{1}c_{1}\nabla\Phi)$

$\frac{\partial c_{2}}{\partial t}=\nabla\cdot(D_{2}\nabla c_{2}+\frac{D_{2}c_{2}}{1-c_{3}}\nabla c_{3}+\frac{D_{2}c_{2}}{1-c_{3}}\nabla\Phi)$

$\frac{\partial c_{3}}{\partial t}=\nabla\cdot(D_{3}\nabla c_{3}+\frac{D_{3}c_{3}}{1-c_{2}}\nabla c_{2}+\frac{D_{3}c_{3}}{1-c_{2}}\nabla\Phi)$

$\sigma\nabla^{2}\Phi+\sum_{i=1}^{3}c_{i}=0$

In the old version FEniCS, I defined the function space as follow:

# Mesh info
w=10;h=0.1*w
mesh=RectangleMesh(Point(0,0),Point(w,h),100,10)
P1=FiniteElement('P',triangle,1)
element=MixedElement([P1,P1,P1,P1]))
# Is it right that how many dofs per node your are using,how many terms 
# will be used in the MixedElement?

# Function space
V=FunctionSpace(mesh,element)
du=TrialFunction(V)
v1,v2,v3,v4=TestFunctions(V)
u=Function(V)
u0=Function(V)

# In the old version, I defined the initial class as follow to compute the initial
# value, but it dosen't work in the newest version. Why?
# Initial Condition
class InitialConditions(Expression):
 def eval(self, values, x):
    values[0] = value1
    values[1] = value2
    values[2] = value3
    values[3] = value4
    if x[0]<w/2.0:
      values[0] = value5
      values[1] = value6
      values[2] = value7
      values[3] = value8
 def value_shape(self):
   return (4,)
 # Then use the interpolation, I can obtain the initial u0 as follow(but it can't work in the newest version, I don't know why?):
 u0.interpolate(InitialConditions())

So, my question is:
1. How to define the function space for a multiple dofs problem(each node has multiple dofs), not a vector field but a multiple scalar components(For example: c1,c2,c3...,cn).
2. How to use some high order element or other different element for these c1,c2,c3,phi? For my case, I don't need to consider VectorFunctionspace or other things. Just some simple 2D-4Node rectangle element or 2D-8Nodes rectangle element for all the c1,c2,c3,phi.
I tried use higher order, but FEniCS given me some warning like "too much gauss points...", some thing like that. How to solve it?
3. How to use Functionspace to interpolate the initial value for each dof. In the old version, I can use the self-defined class (class InitialConditions(...):) and use

u0.interpolate(InitialConditions())

but now it gives me the errors.
4. To my understanding, for a multiple dofs problem,For example 4 dofs each node. Then I can define the test function as follow:

v1,v2,v3,v4=Functions(V)
du=TrialFunction(V)
u0=Function(V)
u0.interpolate(InitialCondition())
c10,c20,c30,phi0=split(u0)
u=Function(V)
c1,c2,c3,phi=split(u)

then after I defined the weak form $L$ for this problem use (v1,v2,v3,v4),(c10,c20,c30,phi0) and
(c1,c2,c3,phi). I can compute the Jacobian of this system in each time step as follow:

a=derivative(L,u,du)
problem=NonlinearVariationalProblem(L,u,bcs=bc,J=a)
solver=NonlinearVariationalSolver(problem)
solver.solve()
u0.assign(u)

Is this understanding right? Because I did some simple test and it seems every is OK. But for a complex case, it's not so easy to do the simulation.

Any helpful suggestion is welcome.

Thank you!

asked Jan 5, 2017 by walkandthink FEniCS Novice (320 points)

1 Answer

+1 vote
 
Best answer

Hi,

Maybe there is some misconception of your DOF or how this translates to FEniCS, because every function you get from your mixed space adds dofs to the entire mesh in every function, or maybe I didn't quite get your question. Regarding the concrete questions:

  1. How to define the function space for a multiple dofs problem(each node has multiple dofs), not a vector field but a multiple scalar components(For example: c1,c2,c3...,cn).

If your problem is having multiple scalar components in each node, your code already does that, dofs are defined for each c_i separately. If your problem is having an arbitrary number of functions, you could do something like

element = MixedElement([P1 for i in range(n)])

and then use that to solve the problem, but it sounds weird. Also I am not sure if 'P' gives the same result as 'CG' (continuous galerkin), so maybe you could change it.


  1. How to use some high order element or other different element for these c1,c2,c3,phi? For my case, I don't need to consider VectorFunctionspace or other things. Just some simple 2D-4Node rectangle element or 2D-8Nodes rectangle element for all the c1,c2,c3,phi.
    I tried use higher order, but FEniCS given me some warning like "too much gauss points...", some thing like that. How to solve it?

This is controled by your element definition. As far as I know, only triangle elements are supportetd by fenics.

P1=FiniteElement('CG',triangle,3)

would use third order Lagrange elements.


  1. How to use Functionspace to interpolate the initial value for each dof. In the old version, I can use the self-defined class (class InitialConditions(...):) and use

u0.interpolate(InitialConditions())
but now it gives me the errors.

When you create the DirichletBC class (for setting boundary conditions) you need only to give give an expression to evaluate on the boundary. It is important what you mentioned about evaluating in many points, which is why when you create an Expression, you have to set the degree, so that the correct number of quadrature points is used. Having said this, there is no need for you to interpolate the initial condition. If you want to set an initial pointyou could do it by solving a linearized version of your problem or by setting a function explicitly, which wouldn't require splitting.

  1. To my understanding, for a multiple dofs problem,For example 4 dofs each node. Then I can define the test function as follow:

So it is algoritymically correct but for you forms it shouold use TestFunction explicitly, just for readability. Not quite sure though.

Best regards!!

answered Jan 5, 2017 by nabarnaf FEniCS User (2,940 points)
selected Jan 7, 2017 by walkandthink

Thank you sincerely for the answer. That's really helpful!!! Thank you!

If you want to set an initial point you could do it by solving a linearized version of your problem or by setting a function explicitly, which wouldn't require splitting

Sorry, I don't get your point. Not splitting is required?

For the initial condition, now I can define an expression like this:

u_init=Expression(('x[0]<=w/8.0?C1a:C1b','x[0]<=w/8.0?C2a:C2b','x[0]<=w/8.0?1.0:1.e-6','0.0'),\
degree=1,w=w,C1a=calpha[0],C1b=cbeta[0],C2a=calpha[1],C2b=cbeta[1])

and then use the Functionspace to interpolate the initial value as follow:

u0=interpolate(u_init,V)
c1,c2,eta,phi=split(u)
c10,c20,eta0,phi0=split(u0)

why I split the u and u0 here is that I want to use Backward Euler time integration method.
For example:

L1=c1*v1*dx-c10*v1*dx+dt*D1*dot(grad(c1),grad(v1))*dx
L2=c2*v2*dx-c20*v2*dx+D2*dt*dot(grad(c2),grad(v2))*dx

This is not correct? Or there are other ways to implement the time dependent problem?

Thank you!

Hi,

Sorry, I understood something else. I don't think you need splitting for this, because you can just define each i itial condition as a separate expression. If you really want to follow the splitting scheme, that is used for splitting in mixed spaces (as far as I know, no idea if it works how you want). It seems more natural to me to just use the corresponding coordinates as

c10 = u0[0]

And so on. Let me know if it doesn't work.

Best regards

Thank you so much for the reply! Thank you!

I tried

c10=u0[0]

and it works!

As you mentioned "Split for mixed spaces"...oh, actually, I'm a lit bit confused about it.

For a very simple case, if I have 3 dofs for each node(c1,c2,c3).
Both of them are scalar. I have three different diffusion equations for them.
So, first I will define a mesh like:

mesh=RectangleMesh(Point1,Point2,nx,ny)

then define the element as follow:

P1=FiniteElement('P',triangle,order)

Since I have three dofs for each node, I'll define a MixedElement or MixdeFunctionspace like this:

element=MixedElement([P1,P1])

then the FunctionSpace can be defined as follow:

V=FunctionSpace(mesh,element)

then the TestFunction can be defined as follow:

 v1,v2=TestFunctions(V)

Is it right for a multiple dofs problem,a coupled problem? If I have 6 dofs(i.e. c1,c2,c3,u1,u2,u3),then I should use

 element=MixedElement([P1,P1,P1,P1,P1,P1])
 V=FunctionSpace(mesh,element)
 v1,v2,v3,v4,v5,v6=TestFunction(V)

I tried to define separate initial condition expression for each c, but can't use a correct Function to do the interpolate work.

 c10=interplote(c1_init,v1)

can't work.

Another question, if I run the following code in FEniCS, it will give me the " WARNING: The number of integration points for each cell will be: 256 Consider using the option 'quadrature_degree' to reduce the number of points"

 P1=FiniteElement('P',triangle,2)
 element=MixedElement([P1,P1,P1,P1,P1])
 V=FunctionSpace(mesh,element)

it seems the MixedElement lead to this problem, some duplicated things happened.

So what makes me confused is, how to define the functionspace and element for the multiple dofs problem correctly?

Thank you!

Fenics abstracts from the dofs in each node, so that you only focus on your variables of interest. Again, use 'CG' in your elements as I am not sure of what 'P' is, and use one of first order to reduce the number of quadrature points required. Also, as I mentioned, there is no need to interpolate your initial condition to use it in your weak formulation, Expressions are enough.

Hi, Thank you for the reply.
Maybe I'm too stupid, I still don't understand the concept of 'Dofs' in FEniCS.

I have one concentration(C), one electric potential($\phi$) and one order parameter($\eta$).
Which means I have a governing equation for concentration, a governing equation for electric potential and a governing equation for order parameter.

These three governing equations are coupled together for the model. That means, for each node in the domain will have three degree of freedom(c,eta,phi). For example, for a rectangle domain, I have a lot of triangle elements('CG' element), and the total number of the nodes is 100, if each node has 3 Dofs and then the total number of Dofs is 300.

Now, how to define the FunctionSpace correctly? Use the MixedFunctionSpace?

Thank you!
Best regards!

Yes, to have many unknowns all you have to do is define a mixed element and split the solution afterwards. Im telling you that the dofs way of thinking isnt quite the fenics style, because you could have a problem where you want to find a scalar quantity and a vector quantity, and so you would need only two spaces, or rather a mixed space of a scalar element and a vector element. Your space would have 2 components but as there is a vector it would have n+1 dofs.

Thank you sincerely!

...