This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

User defined __init__ makes troubles in subdomain definition

+4 votes

I want to dynamically define subdomains. However, passing some values and using an __init__ in the subdomain class definition, leads to troubles when marking an instance of the subdomain later.

Any ideas, how to do this right?

The codesnippet below leads to the error

TypeError: in method 'SubDomain__mark', argument 1 of type 'dolfin::SubDomain const *'

caused by the last line in here:

from dolfin import *

mesh = UnitSquareMesh(12, 12)

cdcoo = dict(xmin=0.4, xmax=0.6, ymin=0.2, ymax=0.3)

# Subdomains of Control 
class ContDomain(SubDomain):
    def __init__(self, ddict):
        self.xmin, self.xmax = ddict['xmin'], ddict['xmax']
        self.ymin, self.ymax = ddict['ymin'], ddict['ymax']
    def inside(self, x, on_boundary):
        return ( between(x[0], (self.xmin, self.xmax)) and
                 between(x[1], (self.ymin, self.ymax)) )

class ContDom2(SubDomain):
    def inside(self, x, on_boundary):
        return ( between(x[0], (0.4, 0.6)) and
                 between(x[1], (0.2, 0.3)) )

domains = CellFunction('uint', mesh)
domains.set_all(0)

# dynamically defined subdomain
contdomain = ContDomain(cdcoo)
# static subdomain
contdomain2 = ContDom2()

# this works
contdomain2.mark(domains, 1)
#this fails
contdomain.mark(domains, 1)
asked Jun 19, 2013 by Jan FEniCS User (8,290 points)
edited Jun 20, 2013 by johanhake

How about calling SubDomain.__init__(self) in __init__?

Thank you, this solves it. Didn't know about the necessity to call the init of the super class. If you turn this into an answer, I can accept it.

That's python philosophy: explicit is better than implicit. For example calling Expression.__init__ is not necessary as it does nothing.

@Jan: SubDomain is a SWIG wrapped C++ class. The only way for a C++ method to know that the object passed is a SubDomain is to instantiate that class, which you do by calling the parent constructor. The parent constructor is automatically called if you do not introduce your own __init__ method.
@Jan Blechta: The reason calling Expression.__init__ does not do anything is that we call the C++ constructor behind the scenes. There is a lot (to much?) of python magic related to the Expression class, which goes beyond intuitive Python coding.

I knew there must be some Johan's magic;-)

1 Answer

+9 votes
 
Best answer

Calling SubDomain.__init__(self) in __init__ should fix the problem.

answered Jun 19, 2013 by johannr FEniCS Expert (17,350 points)
selected Jun 19, 2013 by Jan
...