← Back to team overview

dolfin team mailing list archive

Re: Dealing with incomplete UFL finite elements

 

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.

It probably isn't much harder to construct the element
replacements in ffc code than in ufl code though.

A note about the implementation:
Constructing an element with some parameters retained and
some changed can be implemented as a method on the
FiniteElement class (and subclasses). This will be similar to
the reconstruct method of the Expr hierarchy.

Something like:
class FiniteElement:
    def reconstruct(self, **kwargs):
        family = kwargs.get("family", self._family)
        ...
        return FiniteElement(family, ...)

And similar for subclasses where needed. It could also check
that all parameters are well defined after this operation.

Martin



Follow ups

References