Exemple #1
0
def convert_meshfunctions_to_submesh(mesh, submesh, meshfunctions_on_mesh):
    assert meshfunctions_on_mesh is None or (isinstance(
        meshfunctions_on_mesh, list) and len(meshfunctions_on_mesh) > 0)
    if meshfunctions_on_mesh is None:
        return None
    meshfunctions_on_submesh = list()
    # Create submesh subdomains
    for mesh_subdomain in meshfunctions_on_mesh:
        submesh_subdomain = MeshFunction("size_t", submesh,
                                         mesh_subdomain.dim())
        submesh_subdomain.set_all(0)
        assert submesh_subdomain.dim() in (submesh.topology().dim(),
                                           submesh.topology().dim() - 1)
        if submesh_subdomain.dim() == submesh.topology().dim():
            for submesh_cell in cells(submesh):
                submesh_subdomain.array()[
                    submesh_cell.index()] = mesh_subdomain.array()[
                        submesh.submesh_to_mesh_cell_local_indices[
                            submesh_cell.index()]]
        elif submesh_subdomain.dim() == submesh.topology().dim() - 1:
            for submesh_facet in facets(submesh):
                submesh_subdomain.array()[
                    submesh_facet.index()] = mesh_subdomain.array()[
                        submesh.submesh_to_mesh_facet_local_indices[
                            submesh_facet.index()]]
        else:  # impossible to arrive here anyway, thanks to the assert
            raise TypeError(
                "Invalid arguments in convert_meshfunctions_to_submesh.")
        meshfunctions_on_submesh.append(submesh_subdomain)
    return meshfunctions_on_submesh
def boundaries(mesh):
    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    for f in facets(mesh):
        boundaries.array()[f.index()] = 0
        for v in vertices(f):
            boundaries.array()[f.index()] += v.global_index()
    return boundaries
Exemple #3
0
    def test_convert_diffpack_2d(self):

        from dolfin import Mesh, MPI, MeshFunction

        fname = os.path.join(os.path.dirname(__file__), "data", "diffpack_tri")
        dfname = fname + ".xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.diffpack2xml(fname + ".grid", dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)

        self.assertEqual(mesh.num_vertices(), 41)
        self.assertEqual(mesh.num_cells(), 64)
        self.assertEqual(len(mesh.domains().markers(2)), 64)

        mf_basename = dfname.replace(".xml", "_marker_%d.xml")
        for marker, num in [(1, 10), (2, 5), (3, 5)]:

            mf_name = mf_basename % marker
            mf = MeshFunction("size_t", mesh, mf_name)
            self.assertEqual(sum(mf.array() == marker), num)
            os.unlink(mf_name)

        # Clean up
        os.unlink(dfname)
Exemple #4
0
def mplot_cellfunction(
        cell_function: df.MeshFunction) -> Tuple[plt.Figure, Any]:
    """Return a pseudocolor plot of an unstructured triangular grid."""
    fig, ax = plt.subplots(1)
    tri = mesh2triang(cell_function.mesh())
    ax.tripcolor(tri, facecolors=cell_function.array())
    return fig, ax
Exemple #5
0
    def test_convert_diffpack(self):
        from dolfin import Mesh, MPI, MeshFunction, mpi_comm_world
        if MPI.size(mpi_comm_world()) != 1:
            return
        fname = os.path.join("data", "diffpack_tet")
        dfname = fname + ".xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.diffpack2xml(fname + ".grid", dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        self.assertEqual(mesh.num_vertices(), 27)
        self.assertEqual(mesh.num_cells(), 48)
        self.assertEqual(len(mesh.domains().markers(3)), 48)
        self.assertEqual(len(mesh.domains().markers(2)), 16)

        mf_basename = dfname.replace(".xml", "_marker_%d.xml")
        for marker, num in [(3, 9), (6, 9), (7, 3), (8, 1)]:

            mf_name = mf_basename % marker
            mf = MeshFunction("size_t", mesh, mf_name)
            self.assertEqual(sum(mf.array() == marker), num)
            os.unlink(mf_name)

        # Clean up
        os.unlink(dfname)
Exemple #6
0
def test_mesh_function_assign_2D_cells():
    mesh = UnitSquareMesh(MPI.comm_world, 3, 3)
    ncells = mesh.num_cells()
    f = MeshFunction("int", mesh, mesh.topology.dim, 0)
    for cell in Cells(mesh):
        f[cell] = ncells - cell.index()

    g = MeshValueCollection("int", mesh, 2)
    g.assign(f)
    assert ncells == f.size()
    assert ncells == g.size()

    f2 = MeshFunction("int", mesh, g, 0)

    for cell in Cells(mesh):
        value = ncells - cell.index()
        assert value == g.get_value(cell.index(), 0)
        assert f2[cell] == g.get_value(cell.index(), 0)

    h = MeshValueCollection("int", mesh, 2)
    global_indices = mesh.topology.global_indices(2)
    ncells_global = mesh.num_entities_global(2)
    for cell in Cells(mesh):
        if global_indices[cell.index()] in [5, 8, 10]:
            continue
        value = ncells_global - global_indices[cell.index()]
        h.set_value(cell.index(), int(value))

    f3 = MeshFunction("int", mesh, h, 0)

    values = f3.array()
    values[values > ncells_global] = 0.

    assert MPI.sum(mesh.mpi_comm(), values.sum() * 1.0) == 140.
    def test_convert_diffpack_2d(self):

        from dolfin import Mesh, MPI, MeshFunction, mpi_comm_world

        fname = os.path.join(os.path.dirname(__file__), "data", "diffpack_tri")
        dfname = fname+".xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.diffpack2xml(fname+".grid", dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)

        self.assertEqual(mesh.num_vertices(), 41)
        self.assertEqual(mesh.num_cells(), 64)
        self.assertEqual(len(mesh.domains().markers(2)), 64)

        mf_basename = dfname.replace(".xml", "_marker_%d.xml")
        for marker, num in [(1,10), (2,5), (3,5)]:

            mf_name = mf_basename % marker
            mf = MeshFunction("size_t", mesh, mf_name)
            self.assertEqual(sum(mf.array()==marker), num)
            os.unlink(mf_name)

        # Clean up
        os.unlink(dfname)
Exemple #8
0
  def create(mesh, domain_ids, invert=False):
    """
    Creates a wrapped mesh from a super mesh for a given collection
    of domain IDs.

    *Arguments*
      mesh (:class:`dolfin.Mesh`)
        The mesh.
      domain_ids (:class:`[int]`)
        List of domain IDs
      invert (:class:`bool`)
        Invert list of domain IDs

    *Returns*
      :class:`WrappedMesh`
        The wrapped mesh
    """
    if invert or isinstance(domain_ids, list) or isinstance(domain_ids, tuple):
      if isinstance(domain_ids, int): domain_ids = (domain_ids,)

      subdomains = MeshFunction('size_t', mesh, 3, mesh.domains())
      combined_subdomains = CellFunction("size_t", mesh, 0)
      for domain_id in domain_ids:
        combined_subdomains.array()[subdomains.array() == domain_id] = 1

      submesh = SubMesh(mesh, combined_subdomains, 0 if invert else 1)
    else:
      submesh = SubMesh(mesh, domain_ids)

    submesh.__class__  = WrappedMesh
    submesh._init(mesh)

    return submesh
Exemple #9
0
  def dP(self, domain = "all"):
    """
    Convenience wrapper for integral-point measure. If the mesh does not contain
    any cell domains, the measure for the whole mesh is returned.

    *Arguments*
      domain (:class:`string` / :class:`int`)
        name or ID of domain

    *Returns*
      :class:`dolfin:Measure`
        the measure
    """
    if not self.mesh_has_domains(): return Measure('dP', self.mesh)

    if not self._dP.has_key(domain):
      v = TestFunction(self.FunctionSpace())
      values = assemble(v*self.dx(domain)).array()
      # TODO improve this?
      markers = ((np.sign(np.ceil(values) - 0.5) + 1.0) / 2.0).astype(np.uint64)

      vertex_domains = MeshFunction('size_t', self.mesh, 0)
      vertex_domains.array()[:] = markers

      self._dP[domain] = Measure('dP', self.mesh)[vertex_domains](1)

    return self._dP[domain]
Exemple #10
0
    def test_convert_diffpack(self):
        from dolfin import Mesh, MPI, MeshFunction
        if MPI.num_processes() != 1:
            return
        fname = os.path.join("data", "diffpack_tet")
        dfname = fname+".xml"
        
        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.diffpack2xml(fname+".grid", dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        self.assertEqual(mesh.num_vertices(), 27)
        self.assertEqual(mesh.num_cells(), 48)
        self.assertEqual(mesh.domains().markers(3).size(), 48)
        self.assertEqual(mesh.domains().markers(2).size(), 16)

        mf_basename = dfname.replace(".xml", "_marker_%d.xml")
        for marker, num in [(3, 9), (6, 9), (7, 3), (8, 1)]:

            mf_name = mf_basename % marker
            mf = MeshFunction("uint", mesh, mf_name)
            self.assertEqual(sum(mf.array()==marker), num)
            os.unlink(mf_name)
        
        # Clean up
        os.unlink(dfname)
Exemple #11
0
def load_data(mesh, mesh_f, dim, data):
    '''
    Represent mesh_f over dim entities of mesh as collection of vertices.
    Can have mesh as mesh function or (h5_file, data_set)
    '''
    try:
        h5_file, data_set = mesh_f
        mf = MeshFunction('size_t', mesh, dim, 0)
        h5_file.read(mf, data_set)
    except ValueError:
        mf = mesh_f
        data_set = '%d dim entites' % mf.dim()
            
    # Mapf for encoding entities as vertices
    mesh.init(dim, 0)
    e2v = mesh.topology()(dim, 0)

    tags = set(mf.array())
    # Don't encode zero - we initialize to it
    if 0 in tags: tags.remove(0)
    info('%s evolves tags %r' % (data_set, tags))

    for tag in tags:
        data[(dim, tag)] = np.array([e2v(e.index()) for e in SubsetIterator(mf, tag)],
                                    dtype='uintp')
    return data
Exemple #12
0
    def create(mesh, domain_ids, invert=False):
        """
    Creates a wrapped mesh from a super mesh for a given collection
    of domain IDs.

    *Arguments*
      mesh (:class:`dolfin.Mesh`)
        The mesh.
      domain_ids (:class:`[int]`)
        List of domain IDs
      invert (:class:`bool`)
        Invert list of domain IDs

    *Returns*
      :class:`WrappedMesh`
        The wrapped mesh
    """
        if invert or isinstance(domain_ids, list) or isinstance(
                domain_ids, tuple):
            if isinstance(domain_ids, int): domain_ids = (domain_ids, )

            subdomains = MeshFunction('size_t', mesh, 3, mesh.domains())
            combined_subdomains = CellFunction("size_t", mesh, 0)
            for domain_id in domain_ids:
                combined_subdomains.array()[subdomains.array() ==
                                            domain_id] = 1

            submesh = SubMesh(mesh, combined_subdomains, 0 if invert else 1)
        else:
            submesh = SubMesh(mesh, domain_ids)

        submesh.__class__ = WrappedMesh
        submesh._init(mesh)

        return submesh
def transfer_markers(mesh, f, markers=None):
    '''
    Let mesh be a mesh embedded into mesh(f). Transfer all markers from f 
    to the mesh.
    '''
    # Check that we are embdded
    parent_mesh = f.mesh()
    assert parent_mesh.id() in mesh.parent_entity_map

    # If we are embedded then the transfer is only possible of the lower
    # dimensional entities
    assert f.dim() < mesh.topology().dim()
    cdim = mesh.topology().dim()
    edim = f.dim()  # That of entities

    # All not zeros
    if markers is None: markers = set(f.array()) - set((0, ))

    # The idea is to look up mesh.entities in parent by vertex ids
    child_parent_vertex = mesh.parent_entity_map[parent_mesh.id()][0]
    child_parent_cell = mesh.parent_entity_map[parent_mesh.id()][cdim]
    
    # child_entity -> as vertex in child -> as vertex in parent
    # \- connected child cells -> parent -> cells -> parent cell entities as vertex
    # Entity in terms of vertices
    mesh.init(edim, 0)
    ch_e2v = mesh.topology()(edim, 0)
    # The connected cell; we already have child to parent for cell
    mesh.init(edim, cdim)
    ch_e2c = mesh.topology()(edim, cdim)
    # Then parent entities
    parent_mesh.init(cdim, edim)
    p_c2e = parent_mesh.topology()(cdim, edim)
    # In terms of vertices
    parent_mesh.init(edim, 0)
    p_e2v = parent_mesh.topology()(edim, 0)
    
    child_f = MeshFunction('size_t', mesh, edim, 0)
    ch_values = child_f.array()
    # Assignee
    p_values = f.array()

    for entity in range(len(ch_values)):
        # As vertices in parent
        e_as_vertex = set(child_parent_vertex[v] for v in ch_e2v(entity))

        ch_cells = iter(ch_e2c(entity))
        # One of the cells entities should match
        for ch_cell in ch_cells:
            for p_entity in p_c2e(child_parent_cell[ch_cell]):

                found = p_values[p_entity] in markers and set(p_e2v(p_entity)) == e_as_vertex
                # Can assign color
                if found: break
            if found:
                ch_values[entity] = p_values[p_entity]
                break
            
    return child_f
Exemple #14
0
    def __init__(
        self,
        time: df.Constant,
        mesh: df.Mesh,
        cell_model: CellModel,
        parameters: CoupledODESolverParameters,
        cell_function: df.MeshFunction,
    ) -> None:
        """Initialise parameters. NB! Keep I_s for compatibility"""
        # Store input
        self._mesh = mesh
        self._time = time
        self._model = cell_model  # FIXME: For initial conditions and num states

        # Extract some information from cell model
        self._num_states = self._model.num_states()

        self._parameters = parameters
        _cell_function_tags = set(cell_function.array())
        if not set(self._parameters.valid_cell_tags) <= _cell_function_tags:
            msg = "Valid cell tag not found in cell function. Expected {}, for {}."
            raise ValueError(
                msg.format(set(self._parameters.valid_cell_tags),
                           _cell_function_tags))
        valid_cell_tags = self._parameters.valid_cell_tags

        # Create (vector) function space for potential + states
        self._function_space_VS = df.VectorFunctionSpace(self._mesh,
                                                         "CG",
                                                         1,
                                                         dim=self._num_states +
                                                         1)

        # Initialize solution field
        self.vs_prev = df.Function(self._function_space_VS, name="vs_prev")
        self.vs = df.Function(self._function_space_VS, name="vs")

        self.ode_module = load_module(
            "LatticeODESolver",
            recompile=self._parameters.reload_extension_modules,
            verbose=self._parameters.reload_extension_modules)

        self.ode_solver = self.ode_module.LatticeODESolver(
            self._function_space_VS._cpp_object,
            VectorSizet(cell_function.array()), self._parameters.parameter_map)
def refineMesh(m, l, u):
    cell_markers = MeshFunction('bool', m, 1)
    cell_markers.set_all(False)
    coords = m.coordinates()
    midpoints = 0.5 * (coords[:-1] + coords[1:])
    ref_idx = np.where((midpoints > l) & (midpoints < u))[0]
    cell_markers.array()[ref_idx] = True
    m = refine(m, cell_markers)
    return m
def test_ale():

    # Create some mesh
    mesh = UnitSquareMesh(4, 5)

    # Make some cell function
    # FIXME: Initialization by array indexing is probably
    #        not a good way for parallel test
    cellfunc = MeshFunction('size_t', mesh, mesh.topology().dim())
    cellfunc.array()[0:4] = 0
    cellfunc.array()[4:]  = 1

    # Create submeshes - this does not work in parallel
    submesh0 = SubMesh(mesh, cellfunc, 0)
    submesh1 = SubMesh(mesh, cellfunc, 1)

    # Move submesh0
    disp = Constant(("0.1", "-0.1"))
    ALE.move(submesh0, disp)

    # Move and smooth submesh1 accordignly
    ALE.move(submesh1, submesh0)

    # Move mesh accordingly
    parent_vertex_indices_0 = \
        submesh0.data().array('parent_vertex_indices', 0)
    parent_vertex_indices_1 = \
        submesh1.data().array('parent_vertex_indices', 0)
    mesh.coordinates()[parent_vertex_indices_0[:]] = \
        submesh0.coordinates()[:]
    mesh.coordinates()[parent_vertex_indices_1[:]] = \
        submesh1.coordinates()[:]

    # If test passes here then it is probably working
    # Check for cell quality for sure
    magic_number = 0.28
    rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
    assert rmin > magic_number
Exemple #17
0
def check_boundaries_are_marked(
    mesh: df.Mesh,
    ffun: df.MeshFunction,
    markers: Dict[str, int],
    boundaries: List[str],
) -> None:
    # Check that all boundary faces are marked
    num_boundary_facets = df.BoundaryMesh(mesh, "exterior").num_cells()
    if num_boundary_facets != sum(
        [np.sum(ffun.array() == markers[boundary])
         for boundary in boundaries], ):

        raise RuntimeError(
            ("Not all boundary faces are marked correctly. Make sure all "
             "boundary facets are marked as: {}"
             "").format(", ".join(
                 ["{} = {}".format(k, v) for k, v in markers.items()])), )
Exemple #18
0
 def _init_for_append_if_needed(self):
     # Initialize dof to cells map only the first time
     if len(self.dof_to_cells) == 0:
         self.dof_to_cells = list() # of size len(V)
         for (component, V_component) in enumerate(self.V):
             dof_to_cells = self._compute_dof_to_cells(V_component)
             # Debugging
             log(DEBUG, "DOFs to cells map (component " + str(component) + ") on processor " + str(self.mpi_comm.rank) + ":")
             for (global_dof, cells_) in dof_to_cells.items():
                 log(DEBUG, "\t" + str(global_dof) + ": " + str([cell.global_index() for cell in cells_]))
             # Add to storage
             self.dof_to_cells.append(dof_to_cells)
         self.dof_to_cells = tuple(self.dof_to_cells)
     # Initialize cells marker
     N = self._get_next_index()
     reduced_mesh_markers = MeshFunction("bool", self.mesh, self.mesh.topology().dim())
     reduced_mesh_markers.set_all(False)
     if N > 0:
         reduced_mesh_markers.array()[:] = self.reduced_mesh_markers[N - 1].array()
     assert N not in self.reduced_mesh_markers
     self.reduced_mesh_markers[N] = reduced_mesh_markers
Exemple #19
0
def derived_bcs(V, original_bcs, u_):

    new_bcs = []

    # Check first if user has declared subdomains
    subdomain = original_bcs[0].user_sub_domain()
    if subdomain is None:
        mesh = V.mesh()
        ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
        for i, bc in enumerate(original_bcs):
            bc.apply(u_[0].vector())  # Need to initialize bc
            m = bc.markers()  # Get facet indices of boundary
            ff.array()[m] = i + 1
            new_bcs.append(DirichletBC(V, Constant(0), ff, i + 1))

    else:
        for i, bc in enumerate(original_bcs):
            subdomain = bc.user_sub_domain()
            new_bcs.append(DirichletBC(V, Constant(0), subdomain))

    return new_bcs
Exemple #20
0
def load_data(mesh, h5_file, data_set, dim, data):
    '''
    Fill the data dictionary with data_set representing mesh function with 
    dim over mesh read from h5_file according to key spec expected by tiling 
    algorithm.
    '''
    mf = MeshFunction('size_t', mesh, dim, 0)
    h5_file.read(mf, data_set)
            
    # Data to evolve
    mesh.init(dim, 0)
    e2v = tile.topology()(dim, 0)

    tags = set(mf.array())
    # Don't evolve zero - we initialize to it
    if 0 in tags: tags.remove(0)
    info('%s evolves tags %r' % (data_set, tags))

    for tag in tags:
        data[(dim, tag)] = np.array([e2v(e.index()) for e in SubsetIterator(mf, tag)],
                                    dtype='uintp')
    return data
Exemple #21
0
    def create_boundary(self, domains, interior, exterior):
        """ mark commmon facets between two domains with 1 and a return FacetFunction"""

        edges = MeshFunction("size_t", domains.mesh(),
                             domains.mesh().topology().dim() - 1)
        edges.set_all(0)

        # count number of boundary facets
        Nfacets = 0
        for facet in facets(domains.mesh()):
            cells = facet.entities(2)
            if facet.exterior() == False:

                cell1 = cells[0]
                cell2 = cells[1]
                domain1 = domains.array()[cells[0]]
                domain2 = domains.array()[cells[1]]
                if (sorted([domain1, domain2]) == sorted([interior,
                                                          exterior])):
                    idx = facet.index()
                    edges.array()[idx] = True
                    Nfacets += 1

        return (edges, Nfacets)
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver,
                       bcs=bcs_nut, bounded=True, name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij, nut_form=nut_form, nut_=nut_, delta=delta, bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq, CG1=CG1, Cs=Cs, u_CG1=u_CG1,
                u_filtered=u_filtered, ll=ll, Lij=Lij, Mij=Mij, Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps, Sijmats=Sijmats, JLM=JLM, JMM=JMM, dim=dim,
                tensdim=tensdim, G_matr=G_matr, G_under=G_under, dummy=dummy,
                uiuj_pairs=uiuj_pairs)
    def __init__(
        self,
        time: df.Constant,
        mesh: df.Mesh,
        intracellular_conductivity: Dict[int, df.Expression],
        extracellular_conductivity: Dict[int, df.Expression],
        cell_function: df.MeshFunction,
        cell_tags: CellTags,
        interface_function: df.MeshFunction,
        interface_tags: InterfaceTags,
        parameters: CoupledBidomainParameters,
        neumann_boundary_condition: Dict[int, df.Expression] = None,
        v_prev: df.Function = None,
        surface_to_volume_factor: Union[float, df.Constant] = None,
        membrane_capacitance: Union[float, df.Constant] = None,
    ) -> None:
        self._time = time
        self._mesh = mesh
        self._parameters = parameters

        # Strip none from cell tags
        cell_tags = set(cell_tags) - {None}

        if surface_to_volume_factor is None:
            surface_to_volume_factor = df.constant(1)

        if membrane_capacitance is None:
            membrane_capacitance = df.constant(1)

        # Set Chi*Cm
        self._chi_cm = df.Constant(surface_to_volume_factor) * df.Constant(
            membrane_capacitance)

        if not set(intracellular_conductivity.keys()) == {
                *tuple(extracellular_conductivity.keys())
        }:
            raise ValueError(
                "intracellular conductivity and lambda does not havemnatching keys."
            )
        if not set(cell_tags) == set(intracellular_conductivity.keys()):
            raise ValueError("Cell tags does not match conductivity keys")
        self._intracellular_conductivity = intracellular_conductivity
        self._extracellular_conductivity = extracellular_conductivity

        # Check cell tags
        _cell_function_tags = set(cell_function.array())
        if set(cell_tags) != _cell_function_tags:  # If not equal
            msg = "Mismatching cell tags. Expected {}, got {}"
            raise ValueError(msg.format(set(cell_tags), _cell_function_tags))
        self._cell_tags = set(cell_tags)
        self._cell_function = cell_function

        restrict_tags = self._parameters.restrict_tags
        if set(restrict_tags) >= self._cell_tags:
            msg = "restrict tags ({})is not a subset of cell tags ({})"
            raise ValueError(msg.format(set(restrict_tags), self._cell_tags))
        self._restrict_tags = set(restrict_tags)

        # Check interface tags
        _interface_function_tags = {*set(interface_function.array()), None}
        if not set(interface_tags
                   ) <= _interface_function_tags:  # if not subset of
            msg = "Mismatching interface tags. Expected {}, got {}"
            raise ValueError(
                msg.format(set(interface_tags), _interface_function_tags))
        self._interface_function = interface_function
        self._interface_tags = interface_tags

        # Set up function spaces
        self._transmembrane_function_space = df.FunctionSpace(
            self._mesh, "CG", 1)
        transmembrane_element = df.FiniteElement("CG", self._mesh.ufl_cell(),
                                                 1)
        extracellular_element = df.FiniteElement("CG", self._mesh.ufl_cell(),
                                                 1)

        if neumann_boundary_condition is None:
            self._neumann_bc: Dict[int, df.Expression] = dict()
        else:
            self._neumann_bc = neumann_boundary_condition

        if self._parameters.linear_solver_type == "direct":
            lagrange_element = df.FiniteElement("R", self._mesh.ufl_cell(), 0)
            mixed_element = df.MixedElement(
                (transmembrane_element, extracellular_element,
                 lagrange_element))
        else:
            mixed_element = df.MixedElement(
                (transmembrane_element, extracellular_element))
        self._VUR = df.FunctionSpace(
            mesh, mixed_element)  # TODO: rename to something sensible

        # Set-up solution fields:
        if v_prev is None:
            self._merger = df.FunctionAssigner(
                self._transmembrane_function_space, self._VUR.sub(0))
            self._v_prev = df.Function(self._transmembrane_function_space,
                                       name="v_prev")
        else:
            self._merger = None
            self._v_prev = v_prev
        self._vur = df.Function(self._VUR,
                                name="vur")  # TODO: Give sensible name

        # For normlising rhs_vector. TODO: Unsure about this. Check the nullspace from cbcbeat
        self._extracellular_dofs = np.asarray(self._VUR.sub(1).dofmap().dofs())

        # Mark first timestep
        self._timestep: df.Constant = None
Exemple #24
0
    def model(self, parameters=None, logger=None):
        def format(arr):
            return np.array(arr)

        # Setup parameters, logger
        self.set_parameters(parameters)
        self.set_logger(logger)

        # Get parameters
        parameters = self.get_parameters()

        #SS#if not parameters.get('simulate'):
        #SS#	return

        # Setup data
        self.set_data(reset=True)
        self.set_observables(reset=True)

        # Show simulation settings
        self.get_logger()('\n\t'.join([
            'Simulating:', *[
                '%s : %r' % (param, parameters[param] if not isinstance(
                    parameters[param], dict) else list(parameters[param]))
                for param in
                ['fields', 'num_elem', 'N', 'dt', 'D', 'alpha', 'tol']
            ]
        ]))

        # Data mesh
        mesh = IntervalMesh(MPI.comm_world, parameters['num_elem'],
                            parameters['L_0'], parameters['L_1'])

        # Fields
        V = {}
        W = {}
        fields_n = {}
        fields = {}
        w = {}
        fields_0 = {}
        potential = {}
        potential_derivative = {}
        bcs = {}
        R = {}
        J = {}
        # v2d_vector = {}
        observables = {}
        for field in parameters['fields']:

            # Define functions
            V[field] = {}
            w[field] = {}
            for space in parameters['spaces']:
                V[field][space] = getattr(
                    dolfin, parameters['spaces'][space]['type'])(
                        mesh, parameters['spaces'][space]['family'],
                        parameters['spaces'][space]['degree'])
                w[field][space] = TestFunction(V[field][space])

            space = V[field][parameters['fields'][field]['space']]
            test = w[field][parameters['fields'][field]['space']]

            fields_n[field] = Function(space, name='%sn' % (field))
            fields[field] = Function(space, name=field)

            # Inital condition
            fields_0[field] = Expression(
                parameters['fields'][field]['initial'],
                element=space.ufl_element())
            fields_n[field] = project(fields_0[field], space)
            fields[field].assign(fields_n[field])

            # Define potential
            if parameters['potential'].get('kwargs') is None:
                parameters['potential']['kwargs'] = {}
            for k in parameters['potential']['kwargs']:
                if parameters['potential']['kwargs'][k] is None:
                    parameters['potential']['kwargs'][k] = fields[k]

            potential[field] = Expression(
                parameters['potential']['expression'],
                degree=parameters['potential']['degree'],
                **parameters['potential']['kwargs'])
            potential_derivative[field] = Expression(
                parameters['potential']['derivative'],
                degree=parameters['potential']['degree'] - 1,
                **parameters['potential']['kwargs'])

            #Subdomain for defining Positive grain
            sub_domains = MeshFunction('size_t', mesh,
                                       mesh.topology().dim(), 0)

            #BC condition
            bcs[field] = []
            if parameters['fields'][field]['bcs'] == 'dirichlet':
                BC_l = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_0'])
                BC_r = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_1'])
                bcl = DirichletBC(V, fields_n[field], BC_l)
                bcr = DirichletBC(V, fields_n[field], BC_r)
                bcs[field].extend([bcl, bcr])
            elif parameters['fields'][field]['bcs'] == 'neumann':
                bcs[field].extend([])

            # Residual and Jacobian
            R[field] = (
                ((fields[field] - fields_n[field]) / parameters['dt'] * test *
                 dx) +
                (inner(parameters['D'] * grad(test), grad(fields[field])) * dx)
                + (parameters['alpha'] * potential_derivative[field] * test *
                   dx))

            J[field] = derivative(R[field], fields[field])

            # Observables
            observables[field] = {}

        files = {
            'xdmf': XDMFFile(MPI.comm_world,
                             self.get_paths()['xdmf']),
            'hdf5': HDF5File(MPI.comm_world,
                             self.get_paths()['hdf5'], 'w'),
        }

        files['hdf5'].write(mesh, '/mesh')
        eps = lambda n, key, field, observables, tol: (
            n == 0) or (abs(observables[key]['total_energy'][n] - observables[
                key]['total_energy'][n - 1]) /
                        (observables[key]['total_energy'][0]) > tol)
        flag = {field: True for field in parameters['fields']}
        tol = {
            field: parameters['tol'][field] if isinstance(
                parameters['tol'], dict) else parameters['tol']
            for field in parameters['fields']
        }
        phases = {'p': 1, 'm': 2}
        n = 0
        problem = {}
        solver = {}
        while (n < parameters['N']
               and any([flag[field] for field in parameters['fields']])):

            self.get_logger()('Time: %d' % (n))

            for field in parameters['fields']:

                if not flag[field]:
                    continue

                # Solve
                problem[field] = NonlinearVariationalProblem(
                    R[field], fields[field], bcs[field], J[field])
                solver[field] = NonlinearVariationalSolver(problem[field])
                solver[field].solve()

                # Get field array
                array = assemble(
                    (1 / CellVolume(mesh)) *
                    inner(fields[field], w[field]['Z']) * dx).get_local()

                # Observables
                observables[field]['Time'] = parameters['dt'] * n

                # observables[field]['energy_density'] = format(0.5*dot(grad(fields[field]),grad(fields[field]))*dx)
                observables[field]['gradient_energy'] = format(
                    assemble(0.5 *
                             dot(grad(fields[field]), grad(fields[field])) *
                             dx(domain=mesh)))
                observables[field]['landau_energy'] = format(
                    assemble(potential[field] * dx(domain=mesh)))
                observables[field]['diffusion_energy'] = format(
                    assemble(
                        project(
                            div(project(grad(fields[field]), V[field]['W'])),
                            V[field]['Z']) * dx(domain=mesh))
                )  #Diffusion part of chemical potential
                observables[field]['spinodal_energy'] = format(
                    assemble(
                        potential_derivative[field] *
                        dx(domain=mesh)))  #Spinodal part of chemical potential

                observables[field]['total_energy'] = parameters[
                    'D'] * observables[field]['gradient_energy'] + parameters[
                        'alpha'] * observables[field]['landau_energy']
                observables[field]['chi'] = parameters['alpha'] * observables[
                    field]['diffusion_energy'] - parameters['D'] * observables[
                        field]['spinodal_energy']

                # Phase observables
                sub_domains.set_all(0)
                sub_domains.array()[:] = np.where(array > 0.0, phases['p'],
                                                  phases['m'])

                phases_dxp = Measure('dx',
                                     domain=mesh,
                                     subdomain_data=sub_domains)
                for phase in phases:
                    dxp = phases_dxp(phases[phase])

                    observables[field]['Phi_0%s' % (phase)] = format(
                        assemble(1 * dxp))
                    observables[field]['Phi_1%s' % (phase)] = format(
                        assemble(fields[field] * dxp))
                    observables[field]['Phi_2%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] * dxp))
                    observables[field]['Phi_3%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * dxp))
                    observables[field]['Phi_4%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] * dxp))
                    observables[field]['Phi_5%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] *
                                 fields[field] * dxp))

                    observables[field]['gradient_energy_%s' %
                                       (phase)] = format(
                                           assemble(
                                               0.5 *
                                               dot(grad(fields[field]),
                                                   grad(fields[field])) * dxp))
                    observables[field]['landau_energy_%s' % (phase)] = format(
                        assemble(potential[field] * dxp))
                    observables[field][
                        'total_energy_%s' %
                        (phase)] = parameters['D'] * observables[field][
                            'gradient_energy_%s' %
                            (phase)] + parameters['alpha'] * observables[
                                field]['landau_energy_%s' % (phase)]

                    observables[field][
                        'diffusion_energy_%s' % (phase)] = format(
                            assemble(
                                project(
                                    div(
                                        project(grad(fields[field]),
                                                V[field]['W'])), V[field]['Z'])
                                * dxp))  #Diffusion part of chemical potential
                    observables[field][
                        'spinodal_energy_%s' % (phase)] = format(
                            assemble(
                                potential_derivative[field] *
                                dxp))  #Spinodal part of chemical potential

                    observables[field][
                        'chi_%s' %
                        (phase)] = parameters['alpha'] * observables[field][
                            'spinodal_energy_%s' %
                            (phase)] - parameters['D'] * observables[field][
                                'diffusion_energy_%s' % (phase)]

                files['hdf5'].write(fields[field], '/%s' % (field), n)
                files['xdmf'].write(fields[field], n)

                fields_n[field].assign(fields[field])

                self.set_data({field: array})
                self.set_observables({field: observables[field]})

                flag[field] = eps(n, field, fields[field],
                                  self.get_observables(), tol[field])

            n += 1

        for file in files:
            files[file].close()

        return
Exemple #25
0
    def test_convert_triangle(self): # Disabled because it fails, see FIXME below
        # test no. 1
        from dolfin import Mesh, MPI
        if MPI.num_processes() != 1:
            return
        fname = os.path.join("data", "triangle")
        dfname = fname+".xml"
        
        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        self.assertEqual(mesh.num_vertices(), 96)
        self.assertEqual(mesh.num_cells(), 159)

        # Clean up
        os.unlink(dfname)


        # test no. 2
        from dolfin import MPI, Mesh, MeshFunction, \
                           edges, Edge, faces, Face, \
                           SubsetIterator, facets, CellFunction
        if MPI.num_processes() != 1:
            return
        fname = os.path.join("data", "test_Triangle_3")
        dfname = fname+".xml"
        dfname0 = fname+".attr0.xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        mesh.init()
        mfun = MeshFunction('double', mesh, dfname0)
        self.assertEqual(mesh.num_vertices(), 58)
        self.assertEqual(mesh.num_cells(), 58)

        # Create a size_t CellFunction and assign the values based on the
        # converted Meshfunction
        cf = CellFunction("size_t", mesh)
        cf.array()[mfun.array()==10.0] = 0
        cf.array()[mfun.array()==-10.0] = 1

        # Meassure total area of cells with 1 and 2 marker
        add = lambda x, y : x+y
        area0 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 0)), 0.0)
        area1 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 1)), 0.0)
        total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0)

        # Check that all cells in the two domains are either above or below y=0
        self.assertTrue(all(cell.midpoint().y()<0 for cell in SubsetIterator(cf, 0)))
        self.assertTrue(all(cell.midpoint().y()>0 for cell in SubsetIterator(cf, 1)))
        
        # Check that the areas add up
        self.assertAlmostEqual(area0+area1, total_area)
        
        # Measure the edge length of the two edge domains
        edge_markers = mesh.domains().facet_domains()
        self.assertTrue(edge_markers is not None)
        length0 = reduce(add, (Edge(mesh, e.index()).length() \
                            for e in SubsetIterator(edge_markers, 0)), 0.0)
        length1 = reduce(add, (Edge(mesh, e.index()).length() \
                            for e in SubsetIterator(edge_markers, 1)), 0.0)
        
        # Total length of all edges and total length of boundary edges
        total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0)
        boundary_length = reduce(add, (Edge(mesh, f.index()).length() \
                          for f in facets(mesh) if f.exterior()), 0.0)
        
        # Check that the edges add up
        self.assertAlmostEqual(length0+length1, total_length)
        self.assertAlmostEqual(length1, boundary_length)

        # Clean up
        os.unlink(dfname)
        os.unlink(dfname0)
def test_creation_and_marking():
    class Left(SubDomain):
        def inside(self, x, on_boundary):
            return x[:, 0] < np.finfo(float).eps

    class LeftOnBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return np.logical_and(x[:, 0] < np.finfo(float).eps, on_boundary)

    class Right(SubDomain):
        def inside(self, x, on_boundary):
            return x[:, 0] > 1.0 - np.finfo(float).eps

    class RightOnBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return np.logical_and(x[:, 0] > 1.0 - np.finfo(float).eps,
                                  on_boundary)

    subdomain_pairs = [(Left(), Right()),
                       (LeftOnBoundary(), RightOnBoundary())]

    for ind, MeshClass in enumerate(
        [UnitIntervalMesh, UnitSquareMesh, UnitCubeMesh]):
        dim = ind + 1
        args = [10] * dim
        mesh = MeshClass(MPI.comm_world, *args)
        mesh.create_connectivity_all()

        for left, right in subdomain_pairs:
            for t_dim, f_dim in [(0, 0), (mesh.topology.dim - 1, dim - 1),
                                 (mesh.topology.dim, dim)]:
                f = MeshFunction("size_t", mesh, t_dim, 0)

                left.mark(f, 1)
                right.mark(f, 2)

                correct = {
                    (1, 0): 1,
                    (1, 0): 1,
                    (1, 1): 0,
                    (2, 0): 11,
                    (2, 1): 10,
                    (2, 2): 0,
                    (3, 0): 121,
                    (3, 2): 200,
                    (3, 3): 0
                }

                # Check that the number of marked entities are at least the
                # correct number (it can be larger in parallel)
                assert all(value >= correct[dim, f_dim] for value in [
                    MPI.sum(mesh.mpi_comm(), float((f.array() == 2).sum())),
                    MPI.sum(mesh.mpi_comm(), float((f.array() == 1).sum())),
                ])

        for t_dim, f_dim in [(0, 0), (mesh.topology.dim - 1, dim - 1),
                             (mesh.topology.dim, dim)]:
            f = MeshFunction("size_t", mesh, t_dim, 0)

            class AllTrue(SubDomain):
                def inside(self, x, on_boundary):
                    return np.full(x.shape[0], True)

            class AllFalse(SubDomain):
                def inside(self, x, on_boundary):
                    return np.full(x.shape[0], False)

            empty = AllFalse()
            every = AllTrue()
            empty.mark(f, 1)
            every.mark(f, 2)

            # Check that the number of marked entities is correct
            assert sum(f.array() == 1) == 0
            assert sum(f.array() == 2) == mesh.num_entities(f_dim)
Exemple #27
0
    c2v = dual_mesh.topology()(2, 0)
    for idx_old, (f, l) in enumerate(zip(mapping[:-1], mapping[1:])):
        # f:l are cells of the patch
        idx_new, = reduce(operator.and_, map(set,
                                             (c2v(c) for c in range(f, l))))
        patch_vertices.append(idx_new)

        assert np.linalg.norm(x_old[idx_old] - x_new[idx_new]) < 1E-13

    # The patch overlap vertices are unqiue
    assert len(set(patch_vertices)) == len(patch_vertices)

    File('old_mesh.pvd') << mesh
    # Show how to build the patch mapping from the data of the dual mesh
    cell_f = MeshFunction('size_t', dual_mesh, 2, 0)
    values = cell_f.array()
    for idx, (f, l) in enumerate(zip(mapping[:-1], mapping[1:])):
        values[f:l] = idx

    File('dual_mesh.pvd') << cell_f

    # Scaling
    nvertices, times = [], []
    for n in (4, 8, 16, 32, 64, 128, 256, 512):

        mesh = UnitSquareMesh(n, n)
        nvertices.append(mesh.num_vertices())

        timer = df.Timer('f')
        dual_mesh = DualMesh(mesh)
        time = timer.stop()
# -------------------------------------------------------------------

if __name__ == '__main__':
    from dolfin import (CompiledSubDomain, DomainBoundary, SubsetIterator,
                        UnitSquareMesh, Facet)
    from xii import EmbeddedMesh

    mesh = UnitSquareMesh(4, 4)
    surfaces = MeshFunction('size_t', mesh, 2, 0)
    CompiledSubDomain('x[0] > 0.5-DOLFIN_EPS').mark(surfaces, 1)

    # What should be trasfered
    f = MeshFunction('size_t', mesh, 1, 0)
    DomainBoundary().mark(f, 1)
    CompiledSubDomain('near(x[0], 0.5)').mark(f, 1)
    # Assign funky colors
    for i, e in enumerate(SubsetIterator(f, 1), 1): f[e] = i

    ch_mesh = EmbeddedMesh(surfaces, 1)
    ch_f = transfer_markers(ch_mesh, f)

    # Every color in child is found in parent and we get the midpoint right
    p_values, ch_values = list(f.array()), list(ch_f.array())

    for ch_value in set(ch_f.array()) - set((0, )):
        assert ch_value in p_values

        x = Facet(mesh, p_values.index(ch_value)).midpoint()
        y = Facet(ch_mesh, ch_values.index(ch_value)).midpoint()
        assert x.distance(y) < 1E-13
P1 = FiniteElement('P', 'triangle', 2)
element = MixedElement([P1, P1, P1])
ME = FunctionSpace(mesh, element)

subdomain = CompiledSubDomain(
    '(pow((x[0] - 7.5E-3), 2) + pow((x[1] - 7.5E-3), 2)) <= pow(2.5E-3, 2)')
subdomains = MeshFunction("size_t", mesh, 2)
subdomains.set_all(0)
subdomain.mark(subdomains, 1)

fc = Constant(2.0)  # FCD
V0_r = FunctionSpace(mesh, 'DG', 0)
fc_function = Function(V0_r)
fc_val = [0.0, fc]

help = np.asarray(subdomains.array(), dtype=np.int32)
fc_function.vector()[:] = np.choose(help, fc_val)
zeroth = plot(fc_function, title="Fixed charge density, $c^f$")
plt.colorbar(zeroth)
plot(fc_function)
plt.xlim(0.0, 0.015)
plt.xticks([0.0, 0.005, 0.01, 0.015])
plt.ylim(0.0, 0.015)
plt.yticks([0.0, 0.005, 0.01, 0.015])
plt.show()

Sol_c = Constant(1.0)
Poten = 50.0E-3
l_bc_an = DirichletBC(ME.sub(0), Sol_c, left_boundary)
r_bc_an = DirichletBC(ME.sub(0), Sol_c, right_boundary)
l_bc_ca = DirichletBC(ME.sub(1), Sol_c, left_boundary)
def subdomains(mesh):
    subdomains = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
    for c in cells(mesh):
        subdomains.array()[c.index()] = c.global_index()
    return subdomains
Exemple #31
0
    def test_convert_triangle(
            self):  # Disabled because it fails, see FIXME below

        # test no. 1
        from dolfin import Mesh, MPI

        fname = os.path.join(os.path.dirname(__file__), "data", "triangle")
        dfname = fname + ".xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        self.assertEqual(mesh.num_vertices(), 96)
        self.assertEqual(mesh.num_cells(), 159)

        # Clean up
        os.unlink(dfname)

        # test no. 2
        from dolfin import MPI, Mesh, MeshFunction, \
                           edges, Edge, faces, Face, \
                           SubsetIterator, facets

        fname = os.path.join(os.path.dirname(__file__), "data",
                             "test_Triangle_3")
        dfname = fname + ".xml"
        dfname0 = fname + ".attr0.xml"

        # Read triangle file and convert to a dolfin xml mesh file
        meshconvert.triangle2xml(fname, dfname)

        # Read in dolfin mesh and check number of cells and vertices
        mesh = Mesh(dfname)
        mesh.init()
        mfun = MeshFunction('double', mesh, dfname0)
        self.assertEqual(mesh.num_vertices(), 58)
        self.assertEqual(mesh.num_cells(), 58)

        # Create a size_t MeshFunction and assign the values based on the
        # converted Meshfunction
        cf = MeshFunction("size_t", mesh, mesh.topology().dim())
        cf.array()[mfun.array() == 10.0] = 0
        cf.array()[mfun.array() == -10.0] = 1

        # Meassure total area of cells with 1 and 2 marker
        add = lambda x, y: x + y
        area0 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 0)), 0.0)
        area1 = reduce(add, (Face(mesh, cell.index()).area() \
                             for cell in SubsetIterator(cf, 1)), 0.0)
        total_area = reduce(add, (face.area() for face in faces(mesh)), 0.0)

        # Check that all cells in the two domains are either above or below y=0
        self.assertTrue(
            all(cell.midpoint().y() < 0 for cell in SubsetIterator(cf, 0)))
        self.assertTrue(
            all(cell.midpoint().y() > 0 for cell in SubsetIterator(cf, 1)))

        # Check that the areas add up
        self.assertAlmostEqual(area0 + area1, total_area)

        # Measure the edge length of the two edge domains
        #edge_markers = mesh.domains().facet_domains()
        edge_markers = mesh.domains().markers(mesh.topology().dim() - 1)
        self.assertTrue(edge_markers is not None)
        #length0 = reduce(add, (Edge(mesh, e.index()).length() \
        #                    for e in SubsetIterator(edge_markers, 0)), 0.0)
        length0, length1 = 0.0, 0.0
        for item in list(edge_markers.items()):
            if item[1] == 0:
                e = Edge(mesh, int(item[0]))
                length0 += Edge(mesh, int(item[0])).length()
            elif item[1] == 1:
                length1 += Edge(mesh, int(item[0])).length()

        # Total length of all edges and total length of boundary edges
        total_length = reduce(add, (e.length() for e in edges(mesh)), 0.0)
        boundary_length = reduce(add, (Edge(mesh, f.index()).length() \
                          for f in facets(mesh) if f.exterior()), 0.0)

        # Check that the edges add up
        self.assertAlmostEqual(length0 + length1, total_length)
        self.assertAlmostEqual(length1, boundary_length)

        # Clean up
        os.unlink(dfname)
        os.unlink(dfname0)