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

Python: how to set expansion coefficients for a Function

+3 votes

I need to use analytically calculated expansion coefficients for a Function. Calculation of each coefficient is relatively costly (it is the magnetic field from a coil, calculated by integration over the coil) and I've found that use of Expression is extremely inefficient.

In previous (1.0?) version of dolfin the coefficients were stored quite naturally and I was able get vector of coefficients with function.vector() and simply fill it. Now the scheme is much more complicated and (I guess) I need to access the dof map and use it, but it seems to be a tricky and not stable solution.

Is there any other method?

asked Jun 11, 2013 by jstar FEniCS Novice (280 points)

2 Answers

+2 votes
 
Best answer

Let's assume you have CG1 scalar function u and local expansion coefficients coeff being numpy array ordered according to local vertex indexing.

V = FunctionSpace(mesh, 'CG', 1)
local_range = V.dofmap().ownership_range()
num_local_dofs = local_range[1] - local_range[0]
u = Function(V)
coeff = numpy.zeros(num_local_dofs)

Then

u.vector().set_local(coeff[V.dofmap().vertex_to_dof_map(mesh)])
u.update()

For a vector valued function it may require little modifications.

answered Jun 13, 2013 by Jan Blechta FEniCS Expert (51,420 points)
selected Jun 16, 2013 by Jan Blechta

A quick comment for latecomers like me: In newer versions of FEniCS,

coeff[V.dofmap().vertex_to_dof_map(mesh)

has become:

vertex_to_dof_map(V)
+2 votes

Use of Expression is much more efficient if using C++ compiled expression

# python code
expression = Expression(cpp_code)

instead of subclassing python Expression. Check documentation.

You can instruct DOLFIN not to reorder DOFs

parameters['reorder_dofs_serial'] = False

but you can't do it in parallel.

answered Jun 11, 2013 by Jan Blechta FEniCS Expert (51,420 points)
edited Jun 11, 2013 by Jan Blechta

I had in mind vector norms, min, max, axpy operations, . . .

You complain to high number of evaluations but note that this still scales well.

I'm not complaining, just noticing that even if the algorithm scales well, I'll need to wait for the solution 30+ hours instead of 1 hour.

Note also that someone could give you advice how to speed it up if you tell us how is your Expression computed.

I'm trying to get advice how to set the known expansion coefficients to a dolfin Function. Garth mentioned that I should use the GenericVector interface, but I don't know, how to do it. I have nodal values of my VectorFunction in all nodes of my local (process) mesh. I want to set them as expansion coefficients and my question is: how the values are ordered?
Could you point me to an example of using GenericVector in parallel code?

I'm trying to get advice how to set the known expansion coefficients to a dolfin Function. [...] I want to set them as expansion coefficients and my question is: how the values are ordered?

You did not obtain answer to this question because you have clearly written in your original question:

I need to access the dof map and use it, but it seems to be a tricky and not stable solution. Is there any other method?

But never mind. Let's assume you have CG1 scalar function u and local expansion coefficients coeff being numpy array ordered according to local vertex indexing. Then

u.vector().set_local(coeff[V.dofmap().vertex_to_dof_map(mesh)])
u.update()

I did not test it - just try it. For a vector valued function it needs to be tweaked a little.

It seems to work with my VectorFunction without any tweeking. Thanks!

OK. I added it to a new answer so, please, select is as the best (if everything's working) to close the thread.

...