← Back to team overview

dolfin team mailing list archive

Re: Evaluating the FEM solution at an arbitrary point

 

Anders Logg wrote:
On Sun, Feb 17, 2008 at 10:35:25PM +0100, cosby@xxxxxxxxx wrote:
On Fri, Feb 15, 2008 at 02:46:25PM +0100, cosby@xxxxxxxxx wrote:
On Thu, Feb 14, 2008 at 05:15:46PM +0100, cosby@xxxxxxxxx wrote:
On Thu, Feb 14, 2008 at 10:06:43AM +0100, Kristen Kaasbjerg wrote:
Anders Logg wrote:
On Wed, Feb 13, 2008 at 10:50:23PM +0100, cosby@xxxxxxxxx
wrote:
On Wed, Feb 13, 2008 at 08:49:09PM +0100, Shilpa Khatri
wrote:
We (Dag and I) are doing this because we would like to have
Dolfin
solve
the
Stokes/Navier-Stokes equations as one part of a timestep in
our
code
where we
are moving interfaces that are defined as a random set of
points
in the
domain.

Thanks,
Shilpa

Then I suggest first finding out which cells those points
lie
in,
then
then for each cell with a point get the expansion
coefficients
within
that cell, then multiply those coefficients with the values
of
the
basis functions at the points.

The basis functions are available from the
ufc::finite_element.
We can implement a suitable interface for this at some point
but
until then, you can do it manually.

Sounds good. Is the GTS_Interface still in place for
searching?
/Dag

I'm a little lost here. How is the ufc module used to get hold
of the basis functions ?

Kristen

You need to get hold of a ufc::finite_element and then call
evaluate_basis_function (see UFC manual). If you have a
ufc::form,
then you can create a ufc::finite_element by calling
create_finite_element. If you have a dolfin::Form, then first
get
the
ufc::form by calling form().


Ok, so this is doable via the python interface ?
In case yes, where is the dolfin::Form then hidden ?

Kristen
Yes, you can use it from the Python interface by calling the JIT
compiler:

  (compiled_form, compiled_module, form_data) = jit(a)

You can then call compiled_form.create_finite_element(i) etc
since this will be a Python wrapper for a ufc::form.

BUT: If you are using the Python interface, then everything is
already
available through the Python interface, so if you have a
FiniteElement, you can tabulate it's values at any point by
calling
element.tabulate(). Note that this gives you values on the
reference
element so you need to map the values to the physical element.

Another comment is that things like this are better (more
efficiently)
implemented as C++ components in DOLFIN and then wrapped back to
Python for general use.
Yes, I know. I only have to evaluate the potential at very few
points
(< 100) though, so this wont be too expensive.
What about the expansion coefficients - there must be a set for each
cell ?
You mean getting hold of the expansion coefficients so you can
multiply them with the basis functions? These are in the Vector of
degrees of freedom that each Function has:

  x = u.vector()

Then you need to get hold of the local-to-global mapping (which
values
in this vector that are the coefficients on any given element).

The easiest way to do this is to let DOLFIN handle it by calling
u.interpolate() to get the coefficients on a given cell.

well, it seems to be an awful lot easier than I expected.
It is hard to penetrate these things when an proper overview
of the whole program structure is absent.
Yes, the manual is in a sorry state.

If I understand you correctly then u.interpolate() returns the
coefficients of the basis on a given cell, correct?
Yes.

These then
have to be multiplied by expansion coefficient from u.vector()
which again have to multiplied by the returned array from
element.tabulate(0,([x,y])).
No, it's enough to multiply what you get from u.interpolate() with the
values of the basis functions. (What the interpolation does is just to
pick the correct values from the vector.)

One more thing. How are the coefficient extracted from the vector
from u.vector()
It is done by tabulating the local-to-global mapping (dofmap) on a
cell and then picking the values from the locations in the vector
given by the local-to-global mapping.

and what is the difference between ufc::cell and
dolfin::Cell (arguments for the interpolate attribute of Function)?
ufc::cell is a simple class that is used to pass data through the
UFC-interface (which is not DOLFIN-specific and can be used by other
libraries).

dolfin::Cell is the DOLFIN implementation of a cell in a mesh. What we
do is that we take the dolfin::Cell and then extract the values we
need and put into the ufc::cell. There is a simple class UFCCell (yes,
a third cell class) which helps you do this.
OK, so I now have the outputs from u.interpolate and element.tabulate.
Then I need the wrapping from the reference element to the physical
element. Any easy ways to do this from Python ?
Correction:
OK, so I now have the outputs from u.interpolate and element.tabulate.
Then I need the mapping from the reference element to the physical
element. Any easy ways to do this from Python ?

Kristen

I don't think that should be necessary. The basis functions are
evaluated directly on the physical element so just go ahead and
compute the linear combination.

(The mapping from reference to physical element is built into
evaluate_basis.)

Ok, but then I must have missed something. Let's agree on the
following steps towards the evaluation of the function u in (x,y)
(in python!):
- step #1: find cell that contains (x,y) (has been sorted out)
- step #2: u.interpolate -> expansion coefficients on the given cell
                (has been sorted out)
- step #3: evaluate the basis functions of the relevant element in the
                point (x,y) (not yet sorted out)

How is step #3 to be done in python ? Should the evaluate_basis attribute of the ufc::finite_element be used here ?

Kristen




References