On Fri, Nov 27, 2009 at 11:48:11AM -0800, Johan Hake wrote: > On Friday 27 November 2009 01:20:14 Anders Logg wrote: > > On Thu, Nov 26, 2009 at 10:49:16PM -0800, Johan Hake wrote: > > > On Thursday 26 November 2009 16:09:53 Garth N. Wells wrote: > > > > Anders Logg wrote: > > > > > On Thu, Nov 26, 2009 at 09:42:22PM +0000, Harish Narayanan wrote: > > > > >> Anders Logg wrote: > > > > >>> Looks like the new Expression interface might be working now but > > > > >>> more tests are needed. Please help out getting all the demos over > > > > >>> to the new interface. > > > > >>> > > > > >>> The changes to the interface are as follows: > > > > >>> > > > > >>> 1. V=V argument in Expression should be removed > > > > >>> > > > > >>> 2. mesh argument in Constant should be removed > > > > >>> > > > > >>> 3. Subclasses of Expression overloading eval must overload dim if > > > > >>> not scalar > > > > > > Ok, this might seem to be a bit far fetched but I think it is quite nice. > > > > > > What with: > > > > > > class MyExpression(Expression): > > > def eval(self, x): > > > .... > > > return x_values, y_values > > > > > > The value dimension would then just be the length of the return argument. > > > The _actual_ eval function would then, using the fabulous metaclass, be: > > > > > > def eval(self, values, x): > > > values[0], values[1] = user_eval(self, x) > > > > > > where user_eval is the eval method defined above by the user. > > > > > > This will solve the value dimension problem for python expressions, and > > > make the eval method the user specify more pythonic. > > > > Being able to do return sin(x[0]), cos(x[1]) would be very nice. > > > > But I guess we would still have to implement the dim() function when > > subclassing Expression? > > The point was actually to not do that. My initial thought was to call the user > provided function using a dummy self, (or an initialized one) and a dummy x > arg. Then the number of return argument would decide the value dimension. > > This approach would work for simple Expressions, with no need for a special > initialization. > > class MyExpression(Expression): > def eval(self, x): > return sin(x[0]), cos(x[1]) > > A more complex Expression a la: > > class MyExpression(Expression): > def __init__(self, foo, bar): > self._bar = bar > self._foo = foo > def eval(self, x): > return self._bar.baz*x[0], 2*self._foo > > would be impossible to evaluate as it need both bar and foo, when the class i > constructed. > > So the bottom line is , yes wee need to provide the dim method.
Yes, I think we do. I have thought about doing something like this
before, but the problem is more basic than in your example. We simply
can't tell which values of x are valid inputs. Consider this:
class MyExpression(Expression):
def eval(self, x):
return 1/x[0]
This fails for input x = (0,).
> > > How do we evaluate the value dimension for multi line C++ expression? Do
> > > we require the user to initialize the base Expression class using either
> > > the uint dim constructor or the vector<uint> value_shape constructor?
> > >
> > > If so I do not see that the code in __init__ take care of this case,
> > > yet...
> >
> > I have assumed that the cpparg input is either a single string (and
> > then it's scalar), a tuple of strings (and then it's a vector) or a
> > nested tuple (and then it's a tensor).
>
> Correct. This is how we have used these argument before.
>
> > Are there other cases I have missed?
>
> Yes, the __new__ method is called when a derived class is instantiated too. So
> when one try f = Source(V), the logic tells us that it is a scalar function
> that is instantiated. This can be prevented with some tests of
> course.
ok. Would be good if you took a look at expression.py since you are
more familiar with it. I tried by best but I might have missed some more.
> > > We also need a cleanup of different erroneous user cases. The one that
> > > Garth sketches below, should issue an error. Now it assume the the V is a
> > > "cpparg", and somehow gets through.
> >
> > Yes.
> >
> > > I have also provided the protected attribute _ufl_element. Now there
> > > seems to be an element, and a degree attribute. The latter is OK, but I
> > > think the former should use the _ufl_element attribute, as other code use
> > > the method ufl_element() to access this.
> >
> > ok.
> >
> > > > How should subclaases be initialised?
> > > >
> > > > f = Source(V)
> > > >
> > > > works, but
> > >
> > > Should issue an error.
> > >
> > > > f = Source
> > > >
> > > > doesn't.
> > >
> > > Here you just tell f to be the subclass Source. With the present design
> > > you should just use:
> > >
> > > f = Source()
> > >
> > > I have pushed a fix for a bug that prevented this :)
> >
> > I thought f = Source() worked already. It did when I tested yesterday.
>
> It didn't when I tried.
It worked in the elasticity demo with r = Rotation().
> > Or did you mean you remove the f = Source(V) thing?
>
> No, not yet.
>
> I Can look at it this evening if not someone(TM) has done it
> already.
Great.
> > There were quite a few references to function spaces and V in
> > expression.py when I left it yesterday. Did you clean those out as
> > well?
>
> No, I just tried to get into the changes that has been done.
ok.
--
Anders
signature.asc
Description: Digital signature
_______________________________________________ Mailing list: https://launchpad.net/~dolfin Post to : [email protected] Unsubscribe : https://launchpad.net/~dolfin More help : https://help.launchpad.net/ListHelp

