Anders Logg wrote:
> On Mon, Feb 18, 2008 at 02:29:23PM +0100, Kristen Kaasbjerg wrote:
>   
>> Anders Logg wrote:
>>     
>>> On Mon, Feb 18, 2008 at 02:15:47PM +0100, Kristen Kaasbjerg wrote:
>>>   
>>>       
>>>> Anders Logg wrote:
>>>>     
>>>>         
>>>>> Nice. The obvious thing would be to implement this in DiscreteFunction
>>>>> and map that to the function call
>>>>>
>>>>>   virtual void Function::eval(real* values, const real* x) const;
>>>>>
>>>>> so that any Function (discrete, constant or user-defined) can be
>>>>> evaluated at an arbitrary point.
>>>>>
>>>>> It should be possible to implement this for any kind of element, and
>>>>> the code will look about the same as the code you have done for simple
>>>>> elements.
>>>>>
>>>>> We might add some kind of caching so that evaluation at multiple
>>>>> points that lie close to each other is efficient. (But maybe GTS is
>>>>> smart and handles this already.)
>>>>>
>>>>>   
>>>>>       
>>>>>           
>>>> ok guys, I have made a dirty hack in the C++ Function class
>>>> in order to get the desired functionality. Looks very much like
>>>> Dags code. Could I ask you to take a quick look at it (see below)
>>>> to see if I have done anything alarming. So now both the cell searching 
>>>> and the function evaluation can be done from python (and perhaps be 
>>>> condensed into one function call if desired) and it
>>>> seems to work.
>>>> Thanks for your help along the way.
>>>> Kristen
>>>>
>>>> -----------------------------------------------------------------------------------------------------------
>>>> void Function::my_eval(real* values, const real* x,
>>>>                        const ufc::cell& ufc_cell,
>>>>                        const ufc::finite_element& finite_element,
>>>>                        Cell& cell)
>>>> {
>>>>     if (!f)
>>>>         error("Function contains no data.");
>>>>     //step #1: get expansion coefficient on the cell
>>>>     uint n = finite_element.space_dimension();
>>>>     real* coefficients = new real[n];
>>>>     this->interpolate(coefficients,ufc_cell,finite_element,cell);
>>>>
>>>>     //step #2: multiply with basis functions on the cell
>>>>     real* basis_val = new real[finite_element.value_dimension(0)];
>>>>     for(uint i=0; i<n; i++)
>>>>     {
>>>>         finite_element.evaluate_basis(i,basis_val,x,ufc_cell);
>>>>         values[0] += basis_val[0]*coefficients[i];
>>>>     }
>>>> }
>>>>     
>>>>         
>>> Looks about right, but remember to delete the pointers coefficients
>>> and basis_val.
>>>
>>> Extending this to non-simple elements should be fairly simple. Add
>>> something like this:
>>>
>>>   // Compute size of value (number of entries in tensor value)
>>>   uint size = 1;
>>>   for (uint i = 0; i < finite_element->value_rank(); i++)
>>>     size *= finite_element->value_dimension(i);
>>>
>>> Then iterate over the number of values for each basis function (size),
>>> not only the first.
>>>
>>> Then we just need to include finding the element (using
>>> IntersectionDetector) in this function, remove the arguments ufc_cell,
>>> finite_element and cell, and then this can be added to DiscreteFunction.
>>>
>>>   
>>>       
>> Is the ufc::finite_element available in the Function class ?
>> Kristen
>>     
>
> No, but it's available in DiscreteFunction.
>
>   
Ok, should I try to implement as much of this function as I can ?
How are the Function and DiscreteFunction classes related and
what type is the FEM solution you get out from dolfin ?

Kristen

_______________________________________________
DOLFIN-dev mailing list
[email protected]
http://www.fenics.org/mailman/listinfo/dolfin-dev

Reply via email to