dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #19632
Re: Providing rank to tensor(vector) valued Expression
On 05. sep. 2010 18:48, Anders Logg wrote:
> On Sun, Sep 05, 2010 at 05:33:45PM +0100, Garth N. Wells wrote:
>
>>
>> On 05/09/10 17:22, Johan Hake wrote:
>>
>>> On Sep 5, 2010, at 8:47, Marie Rognes<meg@xxxxxxxxx> wrote:
>>>
>>>
>>>> On 05. sep. 2010 17:36, Johan Hake wrote:
>>>>
>>>>> On Sunday September 5 2010 07:26:19 Anders Logg wrote:
>>>>>
>>>>>
>>>>>> On Sat, Sep 04, 2010 at 08:16:43PM +0200, Marie Rognes wrote:
>>>>>>
>>>>>>
>>>>>>> On 04. sep. 2010 18:26, Johan Hake wrote:
>>>>>>>
>>>>>>>
>>>>>>>> On Saturday September 4 2010 03:54:35 Marie Rognes wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>> On 04. sep. 2010 01:36, Johan Hake wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> Hello!
>>>>>>>>>>
>>>>>>>>>> Garth found an ambiguity in the Expression doc string regarding how a
>>>>>>>>>> user should initiate a user defined Expression (not a compiled one)
>>>>>>>>>> in Python. If the Expression is vector or tensor valued the user
>>>>>>>>>> need to provide information about this.
>>>>>>>>>>
>>>>>>>>>> This can be done in two ways. Either overload the dim method or
>>>>>>>>>> provide a ufl FiniteElement while instantiating the Expression.
>>>>>>>>>> Neither of these methods are documented in the docstring.
>>>>>>>>>>
>>>>>>>>>> In the mixed poisson demo both dim and rank are overloaded. I think
>>>>>>>>>> rank is not needed (works fine without). However dim is just a
>>>>>>>>>> method introduced to be able to automatically select a
>>>>>>>>>> FiniteElement.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> Thanks for bringing this up -- evidently I'm confused.
>>>>>>>>>
>>>>>>>>>
>>>>>>>> Well, me too. Ever since Anders introduced the automatic selection of
>>>>>>>> elements for the Expressions, I have been some what confused.
>>>>>>>>
>>>>>>>>
>>>>>>> Well, that part made perfect sense to me --- I think ;)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>>> First I am not sure dim is the correct name. We could use value_size
>>>>>>>>>> as this is present in the GenericFunction interface for just this
>>>>>>>>>> purpose. Second I am not sure overloading a method is the best and
>>>>>>>>>> most clear way to provide this information. Maybee he could do it
>>>>>>>>>> while instantiating the Expression instead?
>>>>>>>>>>
>>>>>>>>>> class BoundarySource(Expression):
>>>>>>>>>> def eval_data(self, values, data):
>>>>>>>>>> g = sin(5*data.x()[0])
>>>>>>>>>> values[0] = g*data.normal()[0]
>>>>>>>>>> values[1] = g*data.normal()[1]
>>>>>>>>>>
>>>>>>>>>> s = BoundarySource(value_size=2)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> I don't really like the name value_size, but this looks natural to me.
>>>>>>>>> What would it be for matrix-valued functions?
>>>>>>>>>
>>>>>>>>>
>>>>>>>> As I have understand it, value_size is the size of the values array
>>>>>>>> passed to
>>>>>>>>
>>>>>>>> the Expression. So that would then be:
>>>>>>>> value_size = m x n
>>>>>>>>
>>>>>>>> I am not totally happy with the above code as the class should contain
>>>>>>>> everything it needs to be instantiated correctly.
>>>>>>>>
>>>>>>>> Would it make more sense to change the name of dim to value_size?
>>>>>>>>
>>>>>>>>
>>>>>>> Exactly what do you mean here? Keep needing to supply a method "dim",
>>>>>>> but renaming it to "value_size" ? (I still don't find the name
>>>>>>> value_size very intuitive.)
>>>>>>>
>>>>>>>
>>>>>> We have value_rank and value_dimension in the UFC interface. Those are
>>>>>> well defined and well documented. value_size is not something the user
>>>>>> should be worried about, but it is something that comes up in the code
>>>>>> again and again when allocating arrays:
>>>>>>
>>>>>> int value_size = 1;
>>>>>> for (int i = 0; i< value_rank; i++)
>>>>>> value_size *= value_dimension(i)
>>>>>>
>>>>>> Another option would be to set value_shape which is
>>>>>>
>>>>>> int value_shape[value_rank];
>>>>>> for (int i = 0; i< value_rank; i++)
>>>>>> value_shape[i] = value_dimension(i)
>>>>>>
>>>>>>
>>>>> What with:
>>>>>
>>>>> class MyExpression(Expression):
>>>>> def eval(value, x):
>>>>> some_tensor_expression
>>>>> def value_shape(self):
>>>>> return (2,2)
>>>>>
>>>>> If not given we assume, as today, that the value shape is ().
>>>>>
>>>>> One should be able to instantiate it using a not automatically chosen
>>>>> FiniteElement. We add check so the value shape agree with the passed Element.
>>>>>
>>>>>
>>>>
>>>> Side note: At the moment, we allow both specifying a finite element
>>>> and/or a element function space. Should we really allow specifying
>>>> element? Using element (instead of function space) from dolfin seems a
>>>> bit odd to me.
>>>>
>>> We do not accept a FunctionSpace today. We just silently take it and do nothing with it... Will fix.
>>>
>>> I think we landed on just the element as an Expression should not be tied to a mesh.
>>>
>>>
>> That's right - an expression can be evaluated for any x, which is
>> why we use an element (if we use a function space, it's just a lazy
>> way of passing the element). The optional element in the constructor
>> tells the form compiler how to deal with the Expression, rather than
>> having the form compiler choose the element.
>>
> Agree. It is a technical thing that allows advanced users to specify
> how the coefficient should be treated in a form. Therefore we should
> not have a lazy FunctionSpace option that extracts the element since
> that would encourage lazy usage.
>
Ok. (Message delivered very clearly by all parties :) )
--
Marie
References