On Mon, Nov 03, 2008 at 11:38:27AM +0100, Johan Hake wrote: > On Monday 03 November 2008 10:36:52 Martin Sandve Alnæs wrote: > > 2008/11/3 Johan Hake <[EMAIL PROTECTED]>: > > > On Monday 03 November 2008 09:00:58 Martin Sandve Alnæs wrote: > > >> 2008/11/2 Johan Hake <[EMAIL PROTECTED]>: > > >> > On Sunday 02 November 2008 17:44:39 Anders Logg wrote: > > >> >> On Sun, Nov 02, 2008 at 04:28:45PM +0100, Johan Hake wrote: > > >> >> > Hello! > > >> >> > > > >> >> > I have fixed the swig interface so it compiles. I had to add > > >> >> > SubFunction in dolfin_function.h. If we do not want this we have to > > >> >> > add > > >> >> > > > >> >> > #include "SubFunction.h" > > >> >> > > > >> >> > to Function.h, as it is in 0.8.1. > > >> >> > > > >> >> > As function inherits ufc::function I also %imported ufc.h and added > > >> >> > ufc-1 as swig dependencies in scons.cfg. > > >> >> > > > >> >> > I %renamed function.in to function._in and %extended the interface > > >> >> > to SubFunction so one can write > > >> >> > > > >> >> > u in V > > >> >> > > > >> >> > as discussed previously. > > >> >> > > >> >> Very nice! > > >> >> > > >> >> > I am curious of how we will fix the whole PyDOLFIN interface with > > >> >> > the precompiled function spaces aso. These can all be hidden in the > > >> >> > assemble function and/or in the LinearPDE class. But what if we > > >> >> > want to expose a FunctionSpace from a compiled form? Do we want > > >> >> > this? > > >> >> > > > >> >> > Or what if we want to create a FunctionSpace from an element and a > > >> >> > mesh. This can be done more or less in the same way as we have > > >> >> > solved Function in 0.8.1, but then we miss the whole point of > > >> >> > reusing FunctionSpaces. > > >> >> > > > >> >> > Any good suggestions? > > >> >> > > > >> >> > Johan > > >> >> > > >> >> Here's a good suggestion... :-) > > >> >> > > >> >> We create a new Python class (in > > >> >> site-packages/dolfin/functionspace.py) which either inherits from > > >> >> FormCompiler.FiniteElement and > > >> >> dolfin::FunctionSpace or owns such objects as member data. > > >> > > > >> > I suppose it have to inherit from FormCompiler.FiniteElement, but it > > >> > only have to owe a cpp:FunctionSpace. > > >> > > >> To clarify: The (only?) reason for owning and not inheriting is that > > >> we want to reuse function spaces. > > >> > > >> > So the __init__ function in FunctionSpace would be something like: > > >> > > > >> > def __init__(self, mesh, family, order): > > >> > FormCompiler.FiniteElement.__init__\ > > >> > (self,family,dim2shape(mesh.geometry().dim(),order)) > > >> > if self.value_dimension(0) > 1: > > >> > form = ffc.TestFunction(self)[0]*ffc.dx > > >> > else: > > >> > form = ffc.TestFunction(self)*ffc.dx > > >> > (compiled_form, module, form_data) = jit(form,mesh) > > >> > self._V = compiled_form.function_space(0) > > >> > > > >> > and then we can add something like > > >> > > > >> > def cpp_function_space(self): > > >> > return self._V > > >> > > > >> > to the interface, where the latter function is used in the __init__ > > >> > function of the Function class to initialize the cpp_Function? > > >> > > > >> > Maybee we for compatability should let FunctionSpace inherit > > >> > cpp_FunctionSpace. If we do that the __init__ function from above > > >> > would look a bit differently. > > >> > > >> To still allow reusing FunctionSpaces, it would have to be some kind > > >> of envelope-letter design then. > > > > > > Can't it just pass it self to where ever it is needed, instead of passing > > > the function space that it owe? > > > > That's the point of inheritance, yes. And that's why "itself" must act > > as an "envelope" around the "letter" that it owns by forwarding calls, > > giving an envelope-letter design. > > > > >> >> In PyDOLFIN, FunctionSpace will then be something that replaces both > > >> >> FormCompiler.FiniteElement and dolfin::FunctionSpace: > > >> >> > > >> >> V = FunctionSpace(mesh, "Lagrange", 1) > > >> >> v = TestFunction(V) > > >> >> u = TrialFunction(V) > > >> >> f = Function(V) > > >> >> a = dot(grad(v), grad(u))*dx > > >> >> L = v*f*dx > > >> >> A = assemble(a) > > >> >> b = assemble(L) > > >> >> > > >> >> Note that the "triangle" or "tetrahedron" argument is not needed > > >> >> since this can be deduced from the mesh. > > >> > > > >> > Looks nice. Would it then be possible to reuse the cpp_FunctionSpace > > >> > that is initialized for V when the form is compiled using jit? > > >> > > >> The reuse must happen when V is constructed, so this has nothing to do > > >> with compiling forms with jit. > > > > > > If V is constructed as suggested above, see __init__, jit needs to > > > instantiate the functionspace from the compiled form module, and then use > > > this to instantiate the form. (In this case where we only is interested > > > in the actuall function space we do not need jit to instantiate the form > > > though) > > > > That jit is used to compile a finite_element and dof_map in FunctionSpace > > is a separate use of jit from compiling the forms a and L. > > The > > ufl.Form instances > > a and L won't see the dolfin.FunctionSpace, only the ufl.FiniteElement. > > So the form is never instantiated with any function space. > > I think I mixed ufc::Form and dolfin::Form. I thought jit returned a compiled > and instantiated dolfin::Form. But I suppose we then need some form of jit > compiling of a dolfin::Dofmap and dolfin::FiniteElement, based on the > ufc::dofmap, and ufc::FiniteElement that resides in the module returned from > jit today.
There is a new jit() function in FFC that takes a FiniteElement and
returns a compiled ufc::dof_map and ufc::finite_element:
(compiled_element, compiled_dofmap) =3D jit(element)
In the current implementation of assembly/JIT compilation in
PyDOLFIN, we have avoided using dolfin::Form. This is really just a
convenience wrapper that makes life easy in C++ so it's not
necessarily convenient to use from Python.
So, the constructor of FunctionSpace needs to call jit() to get a
compiled ufc::finite_element and a compiled ufc::dof_map. It may then
instantiate the dolfin::FunctionSpace from those two and the Mesh.
--
Anders
> > If we want to construct dolfin.Form objects in PyDOLFIN, we need to do
> > something more.
>
> Ok, I think I am a bit lost with regard to [dolfin,ufc]::Form. The
> dolfin::Assembler takes a dolfin::Form. Where is this "instantiated" today?
>
> > > But when jit is called in the assemble function, it needs to instantiate
> > > the form using the functions spaces that are provided through the
> > > uncompiled form instead of instantiating them from the compiled form
> > > module.
> >
> > Yes. I think that can work out ok. When fetching ufl.FiniteElement objects
> > from a ufl.Form, those objects will actually be the dolfin.FunctionSpace
> > objects because of the inheritance above.
>
> Ok, you go for inheritance then ;)?
>
> > formdata = ufl.FormData(a)
> > # formdata.elements == [V, ...]
> >
> > Thus the mesh will actually be implicitly defined through the function
> > spaces, and can be optional in assemble!
> >
> > So this should be possible:
> >
> > mesh = ...
> > V = FunctionSpace(mesh, "CG", 1)
> > f = Function(V)
> > a = f**2*dx
> > b = assemble(a)
> >
> > or this way for separately defined functions:
> >
> > mesh = ...
> > V = FunctionSpace(mesh, "CG", 1)
> > f = Function(V)
> > a = f**2*dx
> > fc = compiled_function...
> > b = assemble(a, {f: fc})
> >
> > However, I'd still like to be able to define forms separately in .ufl files
> > instead of always having to merge them with the PyDOLFIN application.
>
> Agree.
>
> > In that case we need to instantiate dolfin.FunctionSpace from the elements
> > in a given form. And we need to reuse those across forms, e.g. a and L.
>
> Exactly.
>
> > (But at least then we can get the function names from the .ufl file.)
>
> How is this different from the earlier scenario?
>
> > forms = ufl.load_forms(ufl_filename) # can add returning functions later
> >
> > a, L = forms
> > formdata_a = ufl.FormData(a)
> > formdata_L = ufl.FormData(L)
> >
> > a_spaces = [dolfin.FunctionSpace(mesh, element) for element in
> > formdata_a.elements]
> > L_spaces = [dolfin.FunctionSpace(mesh, element) for element in
> > formdata_a.elements]
> >
> > a_form = dolfin.Form(a, a_spaces)
> >
> > Eh... This is getting complicated.
> > Maybe we can generate PyDOLFIN code as well ;)
>
> If we let jit compile the form with -l dolfin we can extract the
> FunctionSpaces from the module. These will only need a mesh to be
> instantiated.
>
> jit can then be called with either a mesh, which implies that new
> FunctionSpaces are instantiated and used to instantiate the dolfin::form, or
> it can be called with an allready instantiated FunctionSpace(s), which are
> used to instantiate the dolfin::Form.
>
> With this we have reuse of FunctionSpaces, but with the cost that we are
> using
> dolfin::Form instead of ufc::Form.
>
> > >> > I see that this is a very handy way of defining and assemble a form,
> > >> > but would it be possible with this design to define a form using only
> > >> > the FormCompiler language, and then pass this form to jit, or directly
> > >> > to assemble. Then either add the functions manually to the form a là
> > >> > c++ or as it is in the assemble function now, i.e., passing them as an
> > >> > optional kwarg. The latter could be facilitated as Martin suggested
> > >> > previously as
> > >> >
> > >> > assemble(..., coefficients = {'f':f,'g':g},...)
> > >>
> > >> That's not exactly what I suggested, and it won't work here, since the
> > >> names of functions are not known! We just agreed to remove "name" from
> > >> ufl.Function, but if we keep that this would be possible.
> > >>
> > >> What I suggested was using the (FormCompiler.) ufl.Function instances as
> > >> keys:
> > >>
> > >> ...
> > >> fu = ufl.Function(element)
> > >> a = ...*fu*dx
> > >> fc = compiled_function
> > >>
> > >> assemble(a, ..., coefficients = {fu: fc},...)
> > >
> > > Ok!
> > >
> > > Johan
>
>
> Johan
>
> _______________________________________________
> DOLFIN-dev mailing list
> [email protected]
> http://www.fenics.org/mailman/listinfo/dolfin-dev
signature.asc
Description: Digital signature
_______________________________________________ DOLFIN-dev mailing list [email protected] http://www.fenics.org/mailman/listinfo/dolfin-dev
