How to define an array of Constants in UFL

6 months ago by
Hello all,

I am trying to solve a problem with Dolfin C++ interface, I need to define a variational form which includes a term as


The parameter  $k_n$ kn are some known constant need to be defined by user, but n is not known. I need to define a variational form like
  for i in range(n):
  a = sum(list)​

anyone knows how I can do this?
Community: FEniCS Project

2 Answers

6 months ago by
Use the numpy sum function after converting the list to an array.

for i in range(n):
list = np.array(list) a = np.sum(list)
Sorry I did not make my question clear. I want a vector or a list of Constant defined in a UFL file. After I compiling the UFL file with FFC, I would like to be able to give each of the constants a value in the C++ program. Something likes 
# define the surface of each electrode
es0 = Constant(triangle)
es1 = Constant(triangle)
es2 = Constant(triangle)
es3 = Constant(triangle)

esurf = as_vector([es0,es1,es2,es3])​

then I can give es1, es2, etc. a value in C++ code. But this can be done only if I know in advance that there are 4 constants, but if I don't know how many constants I have in advance, and it will be decided later in C++ code, it looks difficult to achieve this. You can also do something like

e1_list = []
e2_list = []
for ie in range(n):

But after compilation with FFC, the names of constants will be given automatically by FFC as w0, w1, w3 ..., then you can not distinguish the constants corresponding to the e1_list from these of e2_list. I guess there is no an automatic solution for this. You need to define the constants one by one as given in the first example here.

written 6 months ago by sin2cos  
I don't have my computer with me to test, but can you not rename the constant with c.rename('%i', % i)?
written 6 months ago by pf4d  
Yes, init with "name" arg:
written 6 months ago by pf4d  
I am not so sure I understand completely. You can not do it since you don't know which name belongs to e1_list or e2_list from C++. As shown in my second example with n = 4, FFC will produce 8 constants named as w0, w1, w2, ..., w8, then I am not so sure how to know which belongs to e1_list from C++.
written 6 months ago by sin2cos  
Also, if you know n at runtime, and you know how you built the constants, you know how to access the vector components too...
written 6 months ago by pf4d  
Yes, you are right. But if we have two vectors, then you will have all constant named sequentially as w0 w1 w2 ..., from which you cannot distinguish the constants of the two lists.
written 6 months ago by sin2cos  
I am not a UFL expert, and was only responding to the python code you posted.  It is trivial to achieve what you need with the python interface.  Perhaps you can convert your C++ code to a dolfin jit-compiled extension.
written 6 months ago by pf4d  
The code posted is actually UFL code. I am still thinking about this problems. I will post my final solution here later on. It seems there is no any way to achieve what I want within UFL. A careful separation of variational form might be helpful.
written 6 months ago by sin2cos  
6 months ago by

you might be interested in considering the following MWE for adding (multiple) ufl-forms (and yes, it really is this easy ;) )
from dolfin import *

mesh = UnitSquareMesh(2,2)
V    = FunctionSpace(mesh,'CG',1)
u    = TrialFunction(V)
v    = TestFunction(V)
uh   = Function(V)

a    = u*v*dx
f    = Constant(0)*v*dx

# List of coefficients
k_list = [1.0, 2.0, 3.0]

# Add forms to f, based on k_list
for k in k_list:
    f += Constant(k)*v*dx
# Solve and plot to check result 
solve(a == f, uh)

Hope this helps.
The OP wants the integration domain to change too, i.e., ds(i)... But that'll work too.
written 6 months ago by pf4d  
Not really what I want to achieve, but still thank you!
written 6 months ago by sin2cos  
Please login to add an answer/comment or follow this question.

Similar posts:
Search »