← Back to team overview

dolfin team mailing list archive

Re: Reading functions from file

 

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])")

?

Then it would be equally simple to grep for ".xml" or similar.

> > > > Also, we need to figure out how to define the file format for
> > > > Functions.
> > > >
> > > > Currently, it looks like this:
> > > >
> > > > <dolfin ...>
> > > >   <function>
> > > >     <mesh ...>
> > > >       ...
> > > >     </mesh>
> > > >     <vector ...>
> > > >       ...
> > > >     </vector>
> > > >     <finiteelement signature="..."/>
> > > >     <dofmap signature="..."/>
> > > >   </function>
> > > > </dolfin>
> > > >
> > > > Should we change the file format to reflect the new design? We would
> > > > need something like this:
> > > >
> > > > <dolfin ...>
> > > >   <function>
> > > >     <functionspace>
> > > >       <mesh>
> > > >         ...
> > > >       </mesh>
> > > >       <finiteelement signature="..."/>
> > > >       <dofmap signature="..."/>
> > > >     </functionspace>
> > > >     <vector ...>
> > > >       ...
> > > >     </vector>
> > > >   </function>
> > > > </dolfin>
> > >
> > > The loaded function instantiate a FunctionSpace in any case, so I guess
> > > the present format is good enough.
> > >
> > > Our problem is that, after we have instantiated the cpp.Function,
> > > together with the cpp.FunctionSpace, we then have to reverse engeneer the
> > > ffc.FiniteElement together with the dolfin.FunctionSpace.
> >
> > Yes.
> >
> > > > 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.

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

> But for that usercase it should be sufficient to construct a cpp.FunctionSpace 
> which can be sent to assemble, e.g:
> 
>   V = cpp.FunctionSpace(mesh,ufc_element,ufc_dofmap)
>   f = Function(V,...) # We need to add support for sending in just 
>                       # a cpp.FunctionSpace to a Function, and then return 
>                       # a cpp.Function
>   
>   A = assemble(compiled_ufc_form,function_spaces=V,coefficients=[f])

Looks good.

-- 
Anders


> We already have checks for cpp.FunctionSpace and cpp.Function for the 
> coefficients.
> 
> I do not know how the coefficient kwarg should work though. 
> 
>   assemble(...,coefficient ={f_ufl:f_cpp}) 
> 
> as the form that is sent in to the assemble function is compiled and does not 
> carry any information about the ufl/ffc coefficient function. Do you have 
> anything to add here Martin?
> 
> 
> Johan

Attachment: signature.asc
Description: Digital signature


Follow ups

References