### How to subclass expression with changeable parameters?

240
views
0
10 months ago by
I basically want the same as this old question: https://fenicsproject.org/qa/4544/how-to-subclass-expression-with-changeable-parameters

However, some functionality appear to have changed since then(?) as I repeatedly get an error for not supplying the expression with a "degree" when creating it.
I tried to simply supply the degree parameter with the rest with no change, but I didn't expect that to work and it doesn't.
Am I supposed to handle the degree parameter somehow in the __init__-function I am making myself, and in this case, what do I do with it?

Thank you
Community: FEniCS Project

4
10 months ago by
Hello,

You don't need to handle the degree parameter on the init method of your expression class... here is a small example how I like to do it:

# Definition of the Expression class
class u_init(Expression):
def __init__(self, **kwargs):
self.left = kwargs["left"]
self.right = kwargs["right"]
def eval(self, values, x):
if x[0] >0.0:
values[0] = self.right
else:
values[0] = self.left
# Usage
u0 = Function(ME)
u0.interpolate(u_init(right=H_so4, left=L_so4, element=ME.ufl_element()))
​

Where "ME" is you function space... You can either define the degree or define the element by using the function space that you are working on...

Alternatively, if you want to use the 'degree', you could call it:
u0.interpolate(u_init(right=1.0, left=0.0, degree=1))​

Regards,
Leonardo
1
Thank you! That seems like a very clean way to do it.
written 10 months ago by Bjørn Jensen
1
10 months ago by

Below is an example from the unit tests. The process is somewhat unclear because of the meta-class magic that goes on behind the scenes. There is a good chance that this will change soon and the behaviour will be more conventional in terms of the initialiser.

class F1(Expression):
def __init__(self, mesh, *arg, **kwargs):
self.mesh = mesh

def eval_cell(self, values, x, cell):
c = Cell(self.mesh, cell.index)
values[0] = sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2])

e1 = F1(mesh, degree=2)