← Back to team overview

dolfin team mailing list archive

Re: ConstantFunctions have undefined value rank and dimension

 

I've imple

2008/7/3 Dag Lindbo <dag@xxxxxxxxxx>:
> Martin Sandve Alnæs wrote:
>> 2008/7/2 Dag Lindbo <dag@xxxxxxxxxx>:
>>> Martin Sandve Alnæs wrote:
>>>> I just added checks for valid Functions to the assembler, but this
>>>> turned out to break some demos so I changed it to warnings.
>>> This seems like helpful checks to make!
>>>
>>>> The reason is that Function(mesh, 0.0), which creates a ConstantFunction,
>>>> is used for zero vector functions as well, which leaves the value shape
>>>> of such a function undefined. This makes error checking impossible,
>>>> which is not very nice.
>>>>
>>>> In my opinion, the correct next step is to keep these warnings,
>>>> and turn them into errors after "a while". We should either add
>>>> support for ConstantFunctions with tensor shape (would be nice),
>>>> or make the demos and apps use user-define functions.
>>> Adding tensor shape to the existing concept of ConstantFunction seems
>>> like the way to go. IMHO, the convenience if this over user defined
>>> functions is too great to discard.
>>>
>>> Would it not just amount to having ConstantFunction::rank() return the
>>> proper value as determined by the mutable member size, instead of 0? (on
>>> line 28 of ConstantFunction.cpp)
>>
>> No, because this size isn't known at construction time, only when
>> interpolate is called with a finite_element object. A suitable (set
>> of) constructor(s) needs to be defined, mirrored in Function, and
>> handled in the swig interface for python.
>
> Yes, I see that this is needed if the rank and shape of the function is
> to be set constructor. Clearly, this makes for a nice user interface! My
> suggestion was more along the lines of a quick fix to get rid of the
> warnings: rank() returns zero if size == 1, returns 1 if size == 2 or 3 etc.
>
> /Dag
>
>>
>> // Scalar constructor
>> Function f(mesh, 0.0);
>>
>> // General tensor constructor:
>> Function f(Mesh& mesh, uint rank, uint* shape, uint* values);
>>
>> // vector
>> uint rank = 1;
>> uint shape[1] = { 2 };
>> real values[2] = { 1., 2. };
>> Function f(mesh, rank, shape, values);
>> // or
>> uint size = 2;
>> real values[2] = { 1., 2. };
>> Function f(mesh, 1, &size, values);
>>
>> // 3x3 tensor:
>> uint rank = 2;
>> uint shape[2] = { 3, 3 };
>> real values[9] = {
>>    1., 2., 3.,
>>    4., 5., 6.,
>>    7., 8., 9. };
>> Function f(mesh, rank, shape, values);
>>
>> --
>> Martin
>
>

I just implemented this, but can't reproduce the old behaviour at the
same time, so the demos must be updated and I guess many user
applications as well. I'd like to have consensus to do this change
before I continue with the demos and check in.

The typical example is a zero function intended to be a vector:
  Function f(mesh, 0.0);

Which now would become:
  uint fsize = 3;
  real fvalues[3] = { 0.0, 0.0, 0.0 };
  Function f(mesh, 1, &fsize, fvalues);

I could evt. add a vector constructor:
  real fvalues[3] = { 0.0, 0.0, 0.0 };
  Function f(mesh, 3, fvalues);

--
Martin


Follow ups

References