Help Using UserExpression in 2018.1


67
views
0
10 days ago by
Hi, I just upgraded to 2018.1. As noted in the changelog, support for overloading Expression was removed, and a new python class UserExpression introduced instead. I'm trying to update my code, a sample below, but keep getting various errors like the one below (object has no attribute '_ufl_shape'). What is the best way to make my code compatible with the new UserExpression?
Thank you!
from dolfin import *
import mshr
radius = 0.25
div = 100
center = Point(1.0, 0.0)
domain = mshr.Circle(center, radius, div)
mesh = mshr.generate_mesh(domain, div, "cgal")
boundarymesh = BoundaryMesh(mesh, 'exterior')
Vs = VectorFunctionSpace(boundarymesh, 'CG', 2) 

class Gamma(UserExpression):
    def __init__(self, center, degree):
        self.center = center
        self.degree = degree

    def eval(self, value, x):
        value[0] = x[0] - self.center[0]
        value[1] = x[1] - self.center[1]

    def value_shape(self):
        return (2,)
    
gamma = project(Gamma(center, degree=1), Vs)​

Traceback (most recent call last):
  File "untitled0.py", line 32, in <module>
    gamma = project(Gamma(center, degree=1), Vs)
  File "/Users/alexanderniewiarowski/anaconda3/envs/fenics2018/lib/python3.6/site-packages/dolfin/fem/projection.py", line 129, in project
    L = ufl.inner(w, v) * dx
  File "/Users/alexanderniewiarowski/anaconda3/envs/fenics2018/lib/python3.6/site-packages/ufl/operators.py", line 144, in inner
    return Inner(a, b)
  File "/Users/alexanderniewiarowski/anaconda3/envs/fenics2018/lib/python3.6/site-packages/ufl/tensoralgebra.py", line 159, in __new__
    ash, bsh = a.ufl_shape, b.ufl_shape
  File "/Users/alexanderniewiarowski/anaconda3/envs/fenics2018/lib/python3.6/site-packages/ufl/coefficient.py", line 73, in ufl_shape
    return self._ufl_shape
AttributeError: 'Gamma' object has no attribute '_ufl_shape'​
Community: FEniCS Project

1 Answer


3
10 days ago by

Your Gamma is a subclass of UserExpression, but to get attributes of the parent class (super class) you need to invoke super() when initialising.

from dolfin import *
import mshr
radius = 0.25
div = 100
center = Point(1.0, 0.0)
domain = mshr.Circle(center, radius, div)
mesh = mshr.generate_mesh(domain, div, "cgal")
boundarymesh = BoundaryMesh(mesh, 'exterior')
Vs = VectorFunctionSpace(boundarymesh, 'CG', 2) 

class Gamma(UserExpression):
    def __init__(self, center, degree, **kwargs):
        self.center = center
        self.degree = degree
        super().__init__(**kwargs)
    
    def eval(self, value, x):
        value[0] = x[0] - self.center[0]
        value[1] = x[1] - self.center[1]
    
    def value_shape(self):
        return (2,)

gamma = project(Gamma(center, degree=1), Vs)
Thank you! Any idea why this was changed?
written 9 days ago by Alexander Niewiarowski  
I don't specifically know why in this case.  But it's a common pattern in object oriented software engineering, it gives you more control over your class.
written 9 days ago by Drew Parsons  
Please login to add an answer/comment or follow this question.

Similar posts:
Search »