dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #11046
Re: Reading functions from file
On Mon, Dec 08, 2008 at 11:51:33PM +0100, Martin Sandve Alnæs wrote:
> 2008/12/8 Anders Logg <logg@xxxxxxxxx>:
> > On Mon, Dec 08, 2008 at 11:25:50PM +0100, Martin Sandve Alnæs wrote:
> >> 2008/12/8 Anders Logg <logg@xxxxxxxxx>:
> >> > On Mon, Dec 08, 2008 at 10:37:15PM +0100, Martin Sandve Alnæs wrote:
> >> >> 2008/12/8 Anders Logg <logg@xxxxxxxxx>:
> >> >> > On Mon, Dec 08, 2008 at 10:28:28PM +0100, Johan Hake wrote:
> >> >> >> On Monday 08 December 2008 22:02:45 Anders Logg wrote:
> >> >> >> > On Mon, Dec 08, 2008 at 09:37:44PM +0100, Johan Hake wrote:
> >> >> >> > > On Monday 08 December 2008 14:53:09 Anders Logg wrote:
> >> >> >> > > > On Mon, Dec 08, 2008 at 02:31:23PM +0100, Johan Hake wrote:
> >> >> >> > > > > On Monday 08 December 2008 13:55:26 Anders Logg wrote:
> >> >> >> > > > > > On Mon, Dec 08, 2008 at 08:01:32AM +0100, Johan Hake wrote:
> >> >> >> > > > > > > On Sunday 07 December 2008 23:33:53 Anders Logg wrote:
> >> >> >> > > > > > > > Something that needs to be added to the new Function interface
> >> >> >> > > > > > > > is reading functions from file. This has worked before:
> >> >> >> > > > > > > >
> >> >> >> > > > > > > > f = Function("function.xml")
> >> >> >> > > > > > > >
> >> >> >> > > > > > > > Can this be added to the metaclass machinery?
> >> >> >> > > > > > >
> >> >> >> > > > > > > No, but to the __new__ function ;) so I guess yes!
> >> >> >> > > > > > >
> >> >> >> > > > > > > The metalclass produces Function classes. The __new__ function
> >> >> >> > > > > > > instantiate new Functions from what ever argument. This is such a
> >> >> >> > > > > > > case.
> >> >> >> > > > > >
> >> >> >> > > > > > It looks like some work is needed to get this in place.
> >> >> >> > > > > >
> >> >> >> > > > > > The "constructor" currently looks as follows:
> >> >> >> > > > > >
> >> >> >> > > > > > def __new__(cls, V, **kwargs):
> >> >> >> > > > > >
> >> >> >> > > > > > so to do
> >> >> >> > > > > >
> >> >> >> > > > > > f = Function("function.xml")
> >> >> >> > > > > >
> >> >> >> > > > > > we need to check if V is a string. Could you add some hooks for
> >> >> >> > > > > > this?
> >> >> >> > > > >
> >> >> >> > > > > I will have a look at it. I do not like V beeing both a FunctionSpace
> >> >> >> > > > > and potentially a filename. I consider having a bunch of kwargs, all
> >> >> >> > > > > defaulting to None. E.g.
> >> >> >> > > > >
> >> >> >> > > > > def __new__(cls, V=None,cpparg=None,defaults=None,filename=None):
> >> >> >> > > > >
> >> >> >> > > > > Then if you create a Function from file you do:
> >> >> >> > > > >
> >> >> >> > > > > f = Function(filename="some_function.xml")
> >> >> >> > > > >
> >> >> >> > > > > the cpparg can the repreresent what is sent to compile_function.
> >> >> >> > > >
> >> >> >> > > > Then it would be different from the C++ constructor (which doesn't
> >> >> >> > > > handle named default arguments) and the Mesh constructor in both C++
> >> >> >> > > > and Python:
> >> >> >> > > >
> >> >> >> > > > mesh = Mesh("mesh.xml")
> >> >> >> > >
> >> >> >> > > The Mesh class has a much clearer C++ interface. It is either
> >> >> >> > > instantiated with a filename-string or from another mesh. The Function
> >> >> >> > > class is a versatile class already in the C++ interface, which defines
> >> >> >> > > different constructors, but evenmore so in the python interface.
> >> >> >> > >
> >> >> >> > > Then I do not think that adding a kwarg for filename is that bad. The
> >> >> >> > > design goal of having as similare interface as possible is good, but then
> >> >> >> > > there are different programming cultures too, to take into acount. I am
> >> >> >> > > not religious about it, but as far as we can I think we should define
> >> >> >> > > kwargs to reflect different instantiation protocol.
> >> >> >> > >
> >> >> >> > > kwargs gives information about how to instantiate a Function. A common
> >> >> >> > > way to figure out how to use a class in python, is to look at the args
> >> >> >> > > and kwargs in class.__init__.
> >> >> >> >
> >> >> >> > ok, sounds reasonable. But didn't you discuss recently to add some
> >> >> >> > magic to differentiate between cppcode and cppexpr by some regexping
> >> >> >> > to enable
> >> >> >> >
> >> >> >> > f = Function(V, "sin(x[0])")
> >> >> >> >
> >> >> >>
> >> >> >> Thats true. It is not allways easy to be consistant :)
> >> >> >>
> >> >> >> But there is a difference between having one argument for either a
> >> >> >> FunctionSpace or a filename, and one argument for anything that can be
> >> >> >> related to the jit compiled functionality.
> >> >> >>
> >> >> >> The only trouble I have now is that all kwargs defaults to None, and one could
> >> >> >> then think that:
> >> >> >>
> >> >> >> f = Function()
> >> >> >>
> >> >> >> would be possible, which it is not. A nice error message should do the trick?
> >> >> >>
> >> >> >> > Then it would be equally simple to grep for ".xml" or similar.
> >> >> >>
> >> >> >> A lot is doable, but not everything should be done. Sounds like a nice quote
> >> >> >> btw ;)
> >> >> >>
> >> >> >> [snip]
> >> >> >>
> >> >> >> > > > > > We also need to change the signature strings so that one may
> >> >> >> > > > > > create form compiler elements (and dofmaps) from the strings.
> >> >> >> > > > > >
> >> >> >> > > > > > The simplest option could be to let the signature be something like
> >> >> >> > > > > >
> >> >> >> > > > > > FiniteElement("Lagrange", "triangle", 1)
> >> >> >> > > > >
> >> >> >> > > > > So you mean substituting the present
> >> >> >> > > > >
> >> >> >> > > > > "Lagrange finite element of degree 1 on a triangle"
> >> >> >> > > > >
> >> >> >> > > > > with the above? Won't this signature be lost in the parsing of the
> >> >> >> > > > > XMLFile, or do you meen that we should parse the function.xml file
> >> >> >> > > > > after we have sent it to cpp.Function() and then extract the element
> >> >> >> > > > > signature?
> >> >> >> > > >
> >> >> >> > > > Yes, first create the cpp.Function, then extract
> >> >> >> > > > v.function_space.element().signature() and use that to create the form
> >> >> >> > > > compiler element. Will that work?
> >> >> >> > >
> >> >> >> > > Yes it will be doable. I didn't know that the FiniteElements in the
> >> >> >> > > elementlibrary all defined its signature. To accomplish this we need to
> >> >> >> > > add some construction options for the dolfin.FunctionSpace though, as it
> >> >> >> > > is too restrictive now.
> >> >> >> >
> >> >> >> > ok.
> >> >> >>
> >> >> >> Some more kwargs? :)
> >> >> >>
> >> >> >> > > Martin has also asked for a way to instantiate a dolfin.FunctionSpace
> >> >> >> > > either with an ufc form or from an ufc_finite_element together with an
> >> >> >> > > ufc_dofmap. We should not forget the pure ufc interface. I think it is
> >> >> >> > > good that Martin keep up that pressure! To reverse engeneer a
> >> >> >> > > dolfin.FunctionSpace from these entities will probably not be doable.
> >> >> >> >
> >> >> >> > Why from a form? That looks like what we had before, which we agreed
> >> >> >> > was crazy (the reason for getting started on all this work with
> >> >> >> > implementing a FunctionSpace class).
> >> >> >>
> >> >> >> Martin?
> >> >> >
> >> >> > Yes, I meant Martin. :-)
> >> >>
> >> >> No matter, using explicit ufc finite_element and dof_map is the most
> >> >> clear and flexible way.
> >> >>
> >> >> (But that difference is definitely _not_ the reason for getting
> >> >> started on the FunctionSpace stuff! Having to repeat (these) multiple
> >> >> arguments for multiple functions on the other hand, that is one of the
> >> >> things FunctionSpace fixes. In this case it's about which arguments to
> >> >> pass to FunctionSpace _once_, so it's just a local issue of (form, i)
> >> >> vs (form.create_finite_element(i), form.create_dof_map(i)) as
> >> >> arguments.)
> >> >
> >> > I'm not sure if we're not talking about the same thing here. But the
> >> > reason we got started on FunctionSpace was that the abstraction was
> >> > missing. Before, we needed to pass forms around everywhere we now use
> >> > a FunctionSpace: for the creation of Functions in C++ and when
> >> > applying boundary conditions (in both C++ and Python).
> >>
> >> A FunctionSpace must also be constructed.
> >
> > It's still a bit weird to create it from the form.
>
> Sure. That wasn't really the point. Going from UFC via whatever to a
> FunctionSpace is the point.
>
> (If the (form, i) stuff was the problem in the old code, we could have
> just replaced it with finite_element and be done, so that's obviously
> not why we need FunctionSpace.)
Do we need to argue about this? I think we agree: we obviously need
the FunctionSpace and it has removed the Form argument from many
places where it was weird to have it.
Maybe you're saying that the FunctionSpace class has also removed some
other arguments that were needed before, like the Mesh, the DofMap and
the FiniteElement? That's also true.
> > I suspect that if we had designed UFC now, we might have added some
> > abstraction for function spaces.
>
> Probably by simply _not_ making the distinction finite_element / dof_map.
Yes, perhaps.
But DofMap has an important role to play that we are currently not
using: the possibility of reordering the dofs which will be
particularly important in parallel.
--
Anders
Attachment:
signature.asc
Description: Digital signature
Follow ups
References
-
Reading functions from file
From: Anders Logg, 2008-12-07
-
Re: Reading functions from file
From: Johan Hake, 2008-12-08
-
Re: Reading functions from file
From: Anders Logg, 2008-12-08
-
Re: Reading functions from file
From: Johan Hake, 2008-12-08
-
Re: Reading functions from file
From: Anders Logg, 2008-12-08
-
Re: Reading functions from file
From: Martin Sandve Alnæs, 2008-12-08
-
Re: Reading functions from file
From: Anders Logg, 2008-12-08
-
Re: Reading functions from file
From: Martin Sandve Alnæs, 2008-12-08
-
Re: Reading functions from file
From: Anders Logg, 2008-12-08
-
Re: Reading functions from file
From: Martin Sandve Alnæs, 2008-12-08