← Back to team overview

dolfin team mailing list archive

Re: Reading functions from file

 

2008/12/9 Anders Logg <logg@xxxxxxxxx>:
> 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.

Never mind. (I was only commenting your comment about my comment about
your comment about Johans comment about something we briefly talked
about over a coffee...)

>> > 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.

Yes, but that part will be in dolfin, right?

It seems finite_element/dof_map and FiniteElement/DofMap always
exist in pairs, and the FiniteElement doesn't use any memory, so
there's probably no reason to separate them?
(After all, now they'll usually be combined in a FunctionSpace).

Are there any places in dolfin where a FiniteElement is used without a
matching DofMap?

--
Martin


Follow ups

References