Subject: [FIAT-dev] Projection of user-defined function

From: Anders Logg <[email-masked]>
Date: Wed, 11 May 2005 17:37:02 -0500

Now that the generation of dof-maps is (mostly) in place in FFC, the
next thing we need to fix is the projection (interpolation) of
user-defined functions onto the finite element space. (The third step
will be evaluation at vertices for post-processing.)

I then need to take a node in FIAT and ask for its coordinate (if the
dual basis is point evaluation). The coordinate I get would then be
mapped from the reference element to the physical element where the
user-defined function is evaluated to obtain its expansion in the
basis.

I could generate this from what I have now, but I also need
coordinates of internal dofs.

Maybe in the future, we might want to do something more general, like
projecting onto the Dubiner basis and doing a linear transformation to
get the expansion at run-time?

/Anders

---

From: Robert C. Kirby <[email-masked]>
Date: Thu, 12 May 2005 09:12:03 -0500

I would suggest that this is too complicated.
We don't need to know the kind of dof to do this

There are two kinds of mappings from functions into function spaces we 
want to consider
i.) The L2 projection
ii.) The nodal interpolant

In order to do the first, we just need the function to be callable -- 
we tabulate at quadrature points and compute (f,phi) for every member 
of the nodal basis.  The dof map matters to piece this together.

In order to do the second, we need the ability to apply our linear 
functionals to the function in consideration.  In the old version of 
FIAT, this was no big deal.  In the new version, every function is a 
polynomial and hence a vector, while every functional is also a vector 
so that it may be applied on the appropriate space by dot product.  I'm 
not sure how to get the real nodal interpolant.  Perhaps I could add a 
feature to functionals so that they could be applied to callable 
objects as well as to polynomials?

In order to get the nodal interpolant on one element, you need
I(f) = n_i(f) \psi_i

where \psi_i is the nodal basis and n_i are the nodes.

On May 11, 2005, at 5:37 PM, Anders Logg wrote:

> _______________________________________________
> FIAT-dev mailing list
> [email-masked]
> http://www.fenics.org/cgi-bin/mailman/listinfo/fiat-dev

---

From: Anders Logg <[email-masked]>
Date: Thu, 12 May 2005 09:45:05 -0500

My suggestion was to do (ii) since I think that would be the easiest
to do at this point (at least for Lagrange).

If I know the coordinates of the nodes on the reference element, then
I can generate code that computes the nodal interpolant of any
callable function at run-time: n_i(f) = f(F_K(x_i)) if F_K is the map
from the reference element.

If coordinates[] is a list of coordinates (mapped from the reference
element to the physical element), then the projection would just look
like

void project(const Function& f, real coefficients[])
{
    coefficient[0] = f(coordinates[0]);
    coefficient[1] = f(coordinates[1]);
    ...
}

For vector-valued elements, I also need to know the vector component
so I can call the user-supplied function with the correct component:

    real operator() (const Point& p, uint i);

/Anders

-- 
Anders Logg
Research Assistant Professor
Toyota Technological Institute at Chicago
http://www.tti-c.org/logg/