← Back to team overview

dolfin team mailing list archive

Re: Collect function data in subclass to prepare for user-defined functions.

 

We could of course have things like time-dependent functions that are
automatically updated and interpolated from a previously saved
solution (saving the primal problem to solve the dual later), but
perhaps we should wait and try to keep things as simple as possible as
long as possible?

Maybe the class (New)Function should always just represent a function
that does not depend on time. We could later add functionality to read
values from a file at a given time, something like

    NewFunction::update(const File& file, real t);

/Anders

On Tue, Feb 15, 2005 at 02:54:42AM -0500, Johan Hoffman wrote:
> 
> Good, I think this is a simple way to handle functions. Weather we use i 
> or comp doesn't matter on my part.
> 
> As for time dependent functions, I think a solution of the form you 
> suggest is good in the case of functions given by expressions. For time 
> dependent functions given as FE functions in discrete time, such as a 
> computed time dependent solution, a user could also declare a function 
> for example given by interpolation in time based on FE functions in 
> discrete time, and where for large problems one would typically write to 
> file.
> 
> So, there are various ways to implement specific functions, and I think it 
> is a good idea to leave much to the user. In particular at this stage, as 
> we need to focus on getting the basics in place. If it turns out that a 
> particular type of function would be very useful, we could add it later 
> on.
> 
> /Johan
> 
> 
> On Mon, 14 Feb 2005, Anders Logg wrote:
> 
> >Yes, I think we should add alternative evaluation operators. But I
> >suggest changing comp to i, and maybe we don't need time. A user that
> >wants a time-dependent function declares her own function and can just
> >put in a public member variable called t and use that:
> >
> >In solver:
> >
> >   f.t = 2.0;
> >
> >In function:
> >
> >class MyFunction : public Function
> >{
> >public:
> >
> >   real operator() (const Point& p)
> >   {
> >      return sin(t)*p.x;
> >   }
> >
> >   real t;
> >
> >}
> >
> >/Anders
> >
> >On Mon, Feb 14, 2005 at 05:52:20PM -0500, Johan Hoffman wrote:
> >>
> >>Looks simple and good, I think. How about vector functions (and time
> >>dependent functions)? Should we add alternative operator() functions to
> >>NewFunction to be implemented by the user:
> >>
> >>virtual real operator()(const Point& p, int comp)
> >>virtual real operator()(const Point& p, real time)
> >>virtual real operator()(const Point& p, int comp, real time)
> >>
> >>or should we introduce new classes?
> >>
> >>/Johan
> >>
> >>On Mon, 14 Feb 2005, Anders Logg wrote:
> >>
> >>>I understand your point. However, I just checked in some updates of
> >>>NewFunction that lets a user do
> >>>
> >>>class MyFunction : NewFunctionExpression
> >>>{
> >>>  real operator()(const Point& p)
> >>> {
> >>>     return sin(p.x);
> >>> }
> >>>};
> >>>
> >>>MyFunction f;
> >>>
> >>>Could you take a look and see if you like the new/old solution?
> >>>It's not very complicated. The projection just checks if data is null
> >>>and in that case calls the user defined evaluation operator.
> >>>
> >>>/Anders
> >>>
> >>>On Mon, Feb 14, 2005 at 03:35:25PM +0100, Johan Jansson wrote:
> >>>
> >>>>I'm thinking about how to enable user-defined functions, but I don't
> >>>>have a clear solution.
> >>>>
> >>>>The idea right now seems to be to subclass NewFunction, a la:
> >>>>
> >>>>// Source term
> >>>>// Example using NewFunction
> >>>>
> >>>>class F : public NewFunction
> >>>>{
> >>>>public:
> >>>> F(const Mesh& mesh, const NewFiniteElement& element, NewVector& x) :
> >>>>   NewFunction(mesh, element, x)
> >>>> {
> >>>> }
> >>>> virtual real operator()(const Point& p)
> >>>> {
> >>>>   real pi = DOLFIN_PI;
> >>>>   return 14.0 * pi*pi * sin(pi*p.x) * sin(2.0*pi*p.y) * 
> >>>>   sin(3.0*pi*p.z);
> >>>> }
> >>>>};
> >>>>
> >>>>We could have a separate constructor when an expression is given, and
> >>>>then project the given expression.
> >>>>
> >>>>I think this is a bit ugly though, it seems unnecessarily complex.
> >>>>
> >>>>Another solution would be to separate the expression out into a
> >>>>functor (function class), and the example would be:
> >>>>
> >>>>class F : Expression
> >>>>{
> >>>> virtual real operator()(const Point& p)
> >>>> {
> >>>>   real pi = DOLFIN_PI;
> >>>>   return 14.0 * pi*pi * sin(pi*p.x) * sin(2.0*pi*p.y) * 
> >>>>   sin(3.0*pi*p.z);
> >>>> }
> >>>>}
> >>>>
> >>>>then:
> >>>>
> >>>>int main()
> >>>>{
> >>>> ...
> >>>>
> >>>> F fexpression;
> >>>> NewFunction f(mesh, element, fexpression);
> >>>>
> >>>> ..
> >>>>}
> >>>>
> >>>>This seems much more natural. When we have a function given by the
> >>>>values of its degrees of freedom, we pass a vector with the dofs to
> >>>>NewFunction. When we have a function given by an expression, we pass
> >>>>the expression to NewFunction and it projects it and stores it as
> >>>>values of the dofs. However, we would need to introduce a new class:
> >>>>Expression. What do you think?
> >>>>
> >>>> Johan
> >>>>
> >>>>_______________________________________________
> >>>>DOLFIN-dev mailing list
> >>>>DOLFIN-dev@xxxxxxxxxx
> >>>>http://www.fenics.org/cgi-bin/mailman/listinfo/dolfin-dev
> >>>>
> >>>
> >>>_______________________________________________
> >>>DOLFIN-dev mailing list
> >>>DOLFIN-dev@xxxxxxxxxx
> >>>http://www.fenics.org/cgi-bin/mailman/listinfo/dolfin-dev
> >>>
> >>>
> >>
> >>_______________________________________________
> >>DOLFIN-dev mailing list
> >>DOLFIN-dev@xxxxxxxxxx
> >>http://www.fenics.org/cgi-bin/mailman/listinfo/dolfin-dev
> >>
> >
> >_______________________________________________
> >DOLFIN-dev mailing list
> >DOLFIN-dev@xxxxxxxxxx
> >http://www.fenics.org/cgi-bin/mailman/listinfo/dolfin-dev
> >
> >
> 
> _______________________________________________
> DOLFIN-dev mailing list
> DOLFIN-dev@xxxxxxxxxx
> http://www.fenics.org/cgi-bin/mailman/listinfo/dolfin-dev
> 



Follow ups

References