← Back to team overview

dolfin team mailing list archive

Re: ConstantFunctions have undefined value rank and dimension

 

2008/7/3 Martin Sandve Alnæs <martinal@xxxxxxxxx>:
> 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);

And:

  Function f(mesh, 3, 0.0);

which does the same as the above.

-- 
Martin


Follow ups

References