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

Different ways of defining sub domain on a mesh

0 votes

I was looking at the documentation provided to create subdomains in Fenics. The following is the way, they defined subdomain. http://fenicsproject.org/documentation/tutorial/materials.html

class Right(SubDomain):
def inside(self, x, on_boundary):
    return True if x[0] = 2 else False

Being new to python and Fenics, I checked how the function 'self' and built in functions are used in Python. But, I am not sure, if I am able to grasp the concept of coding thoroughly. For eg. how is the above code different from:

class Right(SubDomain):
def inside(self, x, on_boundary):
    return near(x[0], 2)  

and this:

def right_boundary(x, on_boundary):
tol = 1E-14   # tolerance for coordinate comparisons
return on_boundary and abs(x[0] - 2) < tol

It' ll be great if some one could explain the return statements implemented here in conjunction with on_boundary. I do understand them to a certain extent but a proper explanation from an expert might prove enlightening. Thanks a lot.

asked Aug 14, 2015 by Chaitanya_Raj_Goyal FEniCS User (4,150 points)
edited Aug 17, 2015 by Chaitanya_Raj_Goyal

2 Answers

0 votes
 
Best answer

In addition to explanation given by multigrid202 above and that provided in Fenics fundamentals documentation; the explanation of use of near() in Fenics is noted below:

class BoundaryLeft(SubDomain):
def inside(self, x, on_boundary):
    return on_boundary and \
        (near(x[0], 0.))

class BoundaryRight(SubDomain):
def inside(self, x, on_boundary):
    return on_boundary and \
        (near(x[0], 1.))

Here the code defines new classes, BoundaryLeft and BoundaryRight, for the left and right boundaries. Note that variables x and y would be denoted by x[0] and x[1], respectively. We define the function "inside" to return true for all x points both on the boundary (on_boundary) and first 0 (near(x[0], 0.), then 1 (near(x[0], 1.). The function "near"(value1,value2) checks that value1 is within machine precision of value2.

answered Aug 18, 2015 by Chaitanya_Raj_Goyal FEniCS User (4,150 points)
selected Aug 18, 2015 by Chaitanya_Raj_Goyal
+1 vote

Hello

I'm not sure I can help you with the second example, because I don't know what near is.

But basically, the expression in the return statement must be boolean, i.e. either True or False. How this True/False value is obtained does not matter. so as long as the function near return a true or false value, you should be fine.

Concerning your first and third example: Unfortunately I cannot find the first example
in the source that you provided. But I think can explain how they are different/the same.

First of all, don't worry about the parameter on_boundary. It gets passed to the function
by fenics automatically and indicates, for a given node/edge, whether or not it is part
of the boundary. I'm not an expert on the internals of Fenics, so it might be good if someone
with more expertise could weigh in here. But basically, fenics does something like: Iterate
over all nodes, take its coordinates and on_boundary value (this value is stored somewhere
along the mesh data). Then put those two values into the "inside" function. If inside returns
true, then the node is part of the subdomain that is currently beeing checked and the respective
boundary condition is later applied.

Theoretically speaking, the two examples (number one and three) are more or less the same. The third example simply
uses some slightly different syntax.

Number 1 is very similar to a "classical" if-statement that you may know from other
programming language. To understand number three, it help to first add some brackets.

def right_boundary(x, on_boundary):
tol = 1E-14   # tolerance for coordinate comparisons
return (on_boundary and (abs(x[0] - 2) < tol))

The term abs(x[0] - 2) < tol evaluates to True or False, depending on... well, whether or not it is true. afterwards the condition on_boundary and (abs(x[0] - 2) < tol) is checked. It returns True, if both expressions left and right of the and are True and false otherwlse.

So the condition simply says."Check the current node. If it is part of the domain boundary
and its x[0]-coordinate is (more or less) equal to two, then consider the node part of the subdomain Right. Otherwise, do nothing".

It should be clear now that examples one and three are logically equivalent. There is a small difference, however, in the way that the x[0]-coordinate is checked.

In the first example, you check it for equality. In the third example, you check it for equality up to a tolerance. Because you are comparing floating point numbers, you should never ever check for actual equality, but always include a tolerance. In your computer, the coordinate
of the the right boundary will be something like 2.000000000000001 or something similar, so it is not strictly equal to 2.

Hope this helps
regards

answered Aug 15, 2015 by multigrid202 FEniCS User (3,780 points)

Thank you. That helps. I' ll see if I can find an explanation on use of "NEAR" as well.

...