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

How does dolfin.SubDomain.map() work?

0 votes

The documentation on the dolfin.SubDomain.map() function states, "Map coordinate x in domain H to coordinate y in domain G." An example of how to use this function is given in the following link in the PeriodicBoundary class.

https://fenicsproject.org/olddocs/dolfin/2016.1.0/python/demo/documented/periodic/python/documentation.html

How does this function work? If I understand correctly in this example the values at x = 0 are mapped to x = 1. I would think we'd want to write the following.

def map(self, x, y):
    y[0] = x[0] + 1.0
    y[1] = x[1]

Instead the example has the following.

def map(self, x, y):
    y[0] = x[0] - 1.0
    y[1] = x[1]

Why is that?
Also, where can I learn more about the inner workings of this function? When I run "map??" I get the same output as "map?".

asked Jan 25, 2017 by aldenpack FEniCS User (1,450 points)

2 Answers

0 votes

Hi, reading the source code showing how the class is used for computing periodic domains should clarify things for you. Basically the role of map is to help find p such that inside(q) == True where q = map(p).

answered Jan 27, 2017 by MiroK FEniCS Expert (80,920 points)
0 votes

Hopefully the following two remarks will answer your question:
First of all, in the 'inside' function you can use whatever variable name to name the coordinate points, so there is no problem if you feel more comfortable by defining the 'inside' function as:

def inside(self, y, on_boundary):
    return bool(y[0] < DOLFIN_EPS and y[0] > -DOLFIN_EPS and on_boundary)

To me, this notation makes clear that 'y' indeed denotes the coordinates of the target domain.
Secondly, what the map practically does, is to assign the same dof number to matching coordinates. To better appreciate this remark, consider the following working example:

from dolfin import * 

class PeriodicBoundary(SubDomain):

    # Left boundary is "target domain" G
    def inside(self, y, on_boundary):
        return bool(y[0] < DOLFIN_EPS and \
                    y[0] > -DOLFIN_EPS and on_boundary)

    # Map right boundary (H) to left boundary (G)
    def map(self, x, y):
        y[0] = x[0] - 1.0
        y[1] = x[1]

mesh = UnitSquareMesh(2,2)

# This is non-periodic
#V    = FunctionSpace(mesh,'CG',1)

# This is Periodic
V    = FunctionSpace(mesh,'CG',1,constrained_domain=PeriodicBoundary())

dofmap = V.dofmap()
print 'Number of dofs', len(dofmap.dofs())

cell_to_dof     = [ [dof for dof in dofmap.cell_dofs(cell)] \
                    for cell in range(mesh.num_cells())]
cell_dof_coords = [V.element().tabulate_dof_coordinates(cell)\
                    for cell in cells(mesh) ] 

for i in range(len(cell_to_dof)):
    print 'Cell', i , 'has dof numbers', cell_to_dof[i],\
        'with dof coordinates: \n', cell_dof_coords[i]
answered Jan 27, 2017 by jmmal FEniCS User (5,890 points)
...