← Back to team overview

dolfin team mailing list archive

Re: Dealing with incomplete UFL finite elements

 

On 29 April 2011 10:20, Anders Logg <logg@xxxxxxxxx> wrote:
> On Fri, Apr 29, 2011 at 09:15:51AM +0100, Garth N. Wells wrote:
>>
>>
>> On 29/04/11 08:58, Martin Sandve Alnæs wrote:
>> > On 29 April 2011 09:35, Anders Logg <logg@xxxxxxxxx> wrote:
>> >> On Thu, Apr 28, 2011 at 10:48:28PM +0100, Garth N. Wells wrote:
>> >>>
>> >>>
>> >>> On 28/04/11 22:17, Anders Logg wrote:
>> >>>> On Thu, Apr 28, 2011 at 12:55:02PM +0200, Martin Sandve Alnæs wrote:
>> >>>>> On 28 April 2011 11:45, Garth N. Wells <gnw20@xxxxxxxxx> wrote:
>> >>>>>>
>> >>>>>>
>> >>>>>> On 27/04/11 20:50, Johan Hake wrote:
>> >>>>>>> On Wednesday April 27 2011 12:45:46 Martin Sandve Alnæs wrote:
>> >>>>>>>> On 27 April 2011 21:34, Anders Logg <logg@xxxxxxxxx> wrote:
>> >>>>>>>>> On Wed, Apr 27, 2011 at 09:30:08PM +0200, Martin Sandve Alnæs wrote:
>> >>>>>>>>>> 2011/4/27 Johan Hake <johan.hake@xxxxxxxxx>
>> >>>>>>>>>>
>> >>>>>>>>>>     On Wednesday April 27 2011 12:03:56 Martin Sandve Aln s wrote:
>> >>>>>>>>>>     > On 27 April 2011 19:07, Garth N. Wells <gnw20@xxxxxxxxx> wrote:
>> >>>>>>>>>>     > > I'm starting here a new thread on how to deal with the recent
>> >>>>>>>>>
>> >>>>>>>>> change in
>> >>>>>>>>>
>> >>>>>>>>>>     > > UFL that has broken a good number of DOLFIN demos. The previous
>> >>>>>>>>>
>> >>>>>>>>> thread
>> >>>>>>>>>
>> >>>>>>>>>>     > > meandered and got side-tracked.
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > The framework in we need to operate is:
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > A. UFL will not allow forms to be modified post-construction.
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > B. It should be relatively easy to replace ufl.Coefficients in
>> >>>>>>>>>>     > > a
>> >>>>>>>>>
>> >>>>>>>>> form
>> >>>>>>>>>
>> >>>>>>>>>>     > > and return a new form.
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > C. The issue with replacing ufl.Coefficients is that we lose
>> >>>>>>>>>
>> >>>>>>>>> DOLFIN
>> >>>>>>>>>
>> >>>>>>>>>>     data
>> >>>>>>>>>>
>> >>>>>>>>>>     > > (like the eval() functions) associated with the removed
>> >>>>>>>>>
>> >>>>>>>>> coefficients.
>> >>>>>>>>>
>> >>>>>>>>>>     > > I'll kick off with the obvious solution:
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > 1. Require that all DOLFIN Expressions are associated with a
>> >>>>>>>>>>     > > ufl.FiniteElement.
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > Other solutions?
>> >>>>>>>>>>     > >
>> >>>>>>>>>>     > > Garth
>> >>>>>>>>>>     >
>> >>>>>>>>>>     > 2.  At the stage when ffc calls ufl.preprocess, or even in
>> >>>>>>>>>>
>> >>>>>>>>>>     ufl.preprocess,
>> >>>>>>>>>>
>> >>>>>>>>>>     > let the preprocessed form contain ufl Coefficients with new
>> >>>>>>>>>
>> >>>>>>>>> elements in
>> >>>>>>>>>
>> >>>>>>>>>>     > place of the dolfin.Expressions. This is similar to the
>> >>>>>>>>>
>> >>>>>>>>> replacements done
>> >>>>>>>>>
>> >>>>>>>>>>     > for renumbering of Coefficients, and could either be done
>> >>>>>>>>>
>> >>>>>>>>> simultaneously
>> >>>>>>>>>
>> >>>>>>>>>>     or
>> >>>>>>>>>>
>> >>>>>>>>>>     > as an additional step. The original Form and Expression objects
>> >>>>>>>>>
>> >>>>>>>>> will be
>> >>>>>>>>>
>> >>>>>>>>>>     > untouched, and the preprocessed form will be fine.
>> >>>>>>>>>>
>> >>>>>>>>>>     +
>> >>>>>>>>>>
>> >>>>>>>>>>     However, setting cell and degree is done during analysis and relies
>> >>>>>>>>>
>> >>>>>>>>> on
>> >>>>>>>>>
>> >>>>>>>>>>     form_data. The form is also preprocessed when the form_data is
>> >>>>>>>>>
>> >>>>>>>>> extracted.
>> >>>>>>>>>
>> >>>>>>>>>>     This
>> >>>>>>>>>>     means that for the preprocessed form to get correct signature, cell
>> >>>>>>>>>
>> >>>>>>>>> and
>> >>>>>>>>>
>> >>>>>>>>>>     degrees being set, we need to break up the logic.
>> >>>>>>>>>>
>> >>>>>>>>>>      1) extract form_data
>> >>>>>>>>>>      2) set degree and cell
>> >>>>>>>>>>      3) genererate preprocessed form
>> >>>>>>>>>>
>> >>>>>>>>>> Lets figure out the exact algorithm if we need it. It could perhaps be
>> >>>>>>>>>> integrated better with preprocess. Or it might be better to extract
>> >>>>>>>>>> just
>> >>>>>>>>>
>> >>>>>>>>> the
>> >>>>>>>>>
>> >>>>>>>>>> information needed to determine degree and cell first, and pass the
>> >>>>>>>>>
>> >>>>>>>>> element
>> >>>>>>>>>
>> >>>>>>>>>> replacements to preprocess.
>> >>>>>>>>>
>> >>>>>>>>> That's what I suggested in an earlier mail. Preprocess already gets
>> >>>>>>>>> common_cell. We could also figure out common_degree before calling
>> >>>>>>>>> preprocess but that requires getting the data stored in
>> >>>>>>>>> form_data.sub_elements.
>> >>>>>>>>
>> >>>>>>>> Extracting all sub elements from a form before preprocessing should be easy
>> >>>>>>>> and efficient.
>> >>>>>>>>
>> >>>>>>>> I assume it's still possible to construct an Expression with a specific
>> >>>>>>>> FunctionSpace?
>> >>>>>>>
>> >>>>>>> Yes.
>> >>>>>>>
>> >>>>>>
>> >>>>>> So it seems we've reached a solution that won't require any changes to
>> >>>>>> DOLFIN, and only minimal changes to FFC. The story is:
>> >>>>>>
>> >>>>>> 1. UFL will permit elements without a cell and without a degree. The
>> >>>>>> will leads an error for some operations, like grad and div.
>> >>>>>>
>> >>>>>> 2. Add a function to UFL to extract all sub-elements from a form.
>> >>>>
>> >>>> The functionality is already there since this is already extracted in
>> >>>> the preprocess function.
>> >>>>
>> >>>
>> >>> We need a function to do this before preprocess in order to pass the
>> >>> cell and element types to the preprocess function.
>> >>
>> >> Yes, but as I just said, we already do that inside preprocess (by
>> >> calling extract_sub_elements) so the functionality is already there to
>> >> be used.
>> >>
>> >>>>>> 3. Add 'unspecified_elements=[]' (perhaps a dict?) to the argument list
>> >>>>>> of ufl.algorithms.preprocess.
>> >>>>
>> >>>> Not sure if this is needed.
>> >>>>
>> >>>>>> 4. For coefficients with incomplete elements, preprocess will replace
>> >>>>>> these with coefficients based on elements from the list
>> >>>>>> 'unspecified_elements'. The new form will be the 'preprocessed form'.
>> >>>>>>
>> >>>>>> Is that it? Anything else?
>> >>>>>>
>> >>>>>> Garth
>> >>>>>
>> >>>>> I think that should be all.
>> >>>>
>> >>>> I think all we need to do (in FFC) is to
>> >>>>
>> >>>> 1. extract the minimal amount of data we need to decide the undecided
>> >>>> degree and cell (essentially building the list of elements)
>> >>>>
>> >>>> 2. select the degree and cell (as we do today)
>> >>>>
>> >>>> 3. pass the degree and cell to compute_form_data (and thus to
>> >>>> preprocess)
>> >>>>
>> >>>
>> >>> Related to my point 3, to keep UFL general, I think that the element
>> >>> should be passed, and not just the degree. It is conceivable that
>> >>> something other than continuous Lagrange elements could be used, which
>> >>> is why an element rather than a degree should be supplied.
>> >>
>> >> I'd prefer if we just got the current functionality in place first
>> >> (without using the now banned set_foo functions) before we make any
>> >> such extensions. I can have a shot at this. If we want to extend it to
>> >> other types of elements, we need to have a long discussion on how to
>> >> choose the element type before we proceed.
>> >
>>
>> I don't see the relevance of this. FFC can just create Lagrange elements
>> of a given degree to pass to UFL. We don't need to discuss the element
>> type at this stage.
>
> It's harder than that since we may have both scalar and vector-valued
> elements.

You have to deal with construction of scalar or vector-valued elements
anyway. It's just a matter of whether this construction is done at the
ffc or ufl side. The reconstruct pattern I mentioned in another mail
is one way to implement the construction at the ufl side, but that can
just as well be called from ffc.

> Would it be enough for now to extract the following to send to UFL:
>
>  common_cell
>  common_family
>  common_degree
>
> ?

Extract that and then do something like
    element_mapping = {}
    for oldelement in elements:
        newelement = oldelement.reconstruct(family=common_family,
cell=common_cell, degree=common_degree)
        element_mapping[oldelement] = newelement
    fd = preprocess(form, element_mapping=element_mapping)
from ffc, then experimentation with other element types can be done
later in ffc without updating ufl.

Martin



Follow ups

References