示例#1
0
    def _build_eval_matrix(V, points):
        """Build the sparse m-by-n matrix that maps a coefficient set for a function in
        V to the values of that function at m given points."""
        # See <https://www.allanswered.com/post/lkbkm/#zxqgk>
        mesh = V.mesh()

        bbt = BoundingBoxTree()
        bbt.build(mesh)
        dofmap = V.dofmap()
        el = V.element()
        sdim = el.space_dimension()

        rows = []
        cols = []
        data = []
        for i, x in enumerate(points):
            cell_id = bbt.compute_first_entity_collision(Point(*x))
            cell = Cell(mesh, cell_id)
            coordinate_dofs = cell.get_vertex_coordinates()

            rows.append(np.full(sdim, i))
            cols.append(dofmap.cell_dofs(cell_id))

            v = el.evaluate_basis_all(x, coordinate_dofs, cell_id)
            data.append(v)

        rows = np.concatenate(rows)
        cols = np.concatenate(cols)
        data = np.concatenate(data)

        m = len(points)
        n = V.dim()
        matrix = sparse.csr_matrix((data, (rows, cols)), shape=(m, n))
        return matrix
示例#2
0
def mesh_fixup(mesh):
    """Refine cells which have all vertices on boundary and
    return a new mesh."""
    cf = CellFunction('bool', mesh)

    tdim = mesh.topology().dim()
    mesh.init(tdim-1, tdim)

    for f in facets(mesh):
        # Boundary facet?
        # TODO: Here we could check supplied facet function or subdomain
        if not f.exterior():
            continue

        # Pick adjacent cell
        c = Cell(mesh, f.entities(tdim)[0])

        # Number of vertices on boundary
        num_bad_vertices = sum(1 for v in vertices(c)
                               if any(fv.exterior() for fv in facets(v)))
        assert num_bad_vertices <= c.num_vertices()

        # Refine cell if all vertices are on boundary
        if num_bad_vertices == c.num_vertices():
            cf[c] = True

    return refine(mesh, cf)
示例#3
0
    def write_fenics_file(ofile, mesh, editor):

        dim = mesh.geometry().dim()
        for i in range(1, len(cell_map) + 1):
            if dim == 2:
                editor.add_cell(i - 1, cell_map[i][0] - 1, cell_map[i][1] - 1,
                                cell_map[i][2] - 1)
            else:
                editor.add_cell(i - 1, cell_map[i][0] - 1, cell_map[i][1] - 1,
                                cell_map[i][2] - 1, cell_map[i][3] - 1)

        mesh.order()
        # Set MeshValueCollections from info in  boundary_cell
        #mvc = mesh.domains().markers(dim-1)
        md = mesh.domains()
        for zone, cells in boundary_cells.iteritems():
            for cell, nds in cells.iteritems():
                dolfin_cell = Cell(mesh, cell - 1)
                vertices_of_cell = dolfin_cell.entities(0)
                vertices_of_face = nds - 1
                for jj, ff in enumerate(facets(dolfin_cell)):
                    facet_vertices = ff.entities(0)
                    if all(map(lambda x: x in vertices_of_face,
                               facet_vertices)):
                        local_index = jj
                        break
                #mvc.set_value(cell-1, local_index, zone)
                md.set_marker((ff.index(), zone), dim - 1)

        ofile << mesh
        from dolfin import plot
        plot(mesh, interactive=True)
        print 'Finished writing FEniCS mesh\n'
示例#4
0
 def write_fenics_file(ofile, mesh, editor):
     
     dim = mesh.geometry().dim()
     for i in range(1, len(cell_map)+1):
         if dim == 2:
             editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1)
         else:
             editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1, cell_map[i][3]-1)
     
     mesh.order()
     # Set MeshValueCollections from info in  boundary_cell
     #mvc = mesh.domains().markers(dim-1)
     md = mesh.domains()
     for zone, cells in boundary_cells.iteritems():
         for cell, nds in cells.iteritems():
             dolfin_cell = Cell(mesh, cell-1)
             vertices_of_cell = dolfin_cell.entities(0)
             vertices_of_face = nds - 1
             for jj, ff in enumerate(facets(dolfin_cell)):
                 facet_vertices = ff.entities(0)
                 if all(map(lambda x: x in vertices_of_face, facet_vertices)):
                     local_index = jj
                     break
             #mvc.set_value(cell-1, local_index, zone)
             md.set_marker((ff.index(), zone), dim-1)
             
     ofile << mesh        
     from dolfin import plot
     plot(mesh, interactive=True)
     print 'Finished writing FEniCS mesh\n'
示例#5
0
def test_distance_interval():

    mesh = UnitIntervalMesh(MPI.comm_self, 1)
    cell = Cell(mesh, 0)

    assert round(cell.distance(Point(-1.0)) - 1.0, 7) == 0
    assert round(cell.distance(Point(0.5)) - 0.0, 7) == 0
示例#6
0
def test_multi_ps_vector(mesh):
    """Tests point source PointSource(V, source) for mulitple point
    sources applied to a vector for 1D, 2D and 3D. Global points given
    to constructor from rank 0 processor.

    """

    c_ids = [0, 1, 2]
    rank = MPI.rank(mesh.mpi_comm())
    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0) * v * dx)

    source = []
    if rank == 0:
        for c_id in c_ids:
            cell = Cell(mesh, c_id)
            point = cell.midpoint()
            source.append((point, 10.0))
    ps = PointSource(V, source)
    ps.apply(b)

    # Checks b sums to correct value
    b_sum = b.sum()
    assert round(b_sum - len(c_ids) * 10.0) == 0
示例#7
0
def test_multi_ps_vector(mesh):
    """Tests point source PointSource(V, source) for mulitple point
    sources applied to a vector for 1D, 2D and 3D. Global points given
    to constructor from rank 0 processor.

    """

    c_ids = [0, 1, 2]
    rank = MPI.rank(mesh.mpi_comm())
    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0)*v*dx)

    source = []
    if rank == 0:
        for c_id in c_ids:
            cell = Cell(mesh, c_id)
            point = cell.midpoint()
            source.append((point, 10.0))
    ps = PointSource(V, source)
    ps.apply(b)

    # Checks b sums to correct value
    b_sum = b.sum()
    assert round(b_sum - len(c_ids)*10.0) == 0
示例#8
0
def test_multi_ps_matrix(mesh):
    """Tests point source PointSource(V, source) for mulitple point
    sources applied to a matrix for 1D, 2D and 3D. Global points given
    to constructor from rank 0 processor.

    """

    c_ids = [0, 1, 2]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    A = assemble(Constant(0.0)*dot(u, v)*dx)

    source = []
    if rank == 0:
        for c_id in c_ids:
            cell = Cell(mesh, c_id)
            point = cell.midpoint()
            source.append((point, 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks b sums to correct value
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2*len(c_ids)*10) == 0
示例#9
0
def test_distance_interval():

    mesh = UnitIntervalMesh(MPI.comm_self, 1)
    cell = Cell(mesh, 0)

    assert round(cell.distance(numpy.array([-1.0, 0, 0])) - 1.0, 7) == 0
    assert round(cell.distance(numpy.array([0.5, 0, 0])) - 0.0, 7) == 0
示例#10
0
def test_multi_ps_matrix(mesh):
    """Tests point source PointSource(V, source) for mulitple point
    sources applied to a matrix for 1D, 2D and 3D. Global points given
    to constructor from rank 0 processor.

    """

    c_ids = [0, 1, 2]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    A = assemble(Constant(0.0) * dot(u, v) * dx)

    source = []
    if rank == 0:
        for c_id in c_ids:
            cell = Cell(mesh, c_id)
            point = cell.midpoint()
            source.append((point, 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks b sums to correct value
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2 * len(c_ids) * 10) == 0
示例#11
0
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        shape = V.ufl_element().value_shape()
        degree = V.ufl_element().degree()

        # A fake instanc to talk to with the world
        adapter = type(
            'MiroHack', (Expression, ), {
                'value_shape': lambda self_, : shape,
                'eval': lambda self_, values, x: self.eval(values, x)
            })
        self.__adapter = adapter(degree=degree)

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry(
        ).dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())
示例#12
0
def test_distance_triangle():

    mesh = UnitSquareMesh(MPI.comm_self, 1, 1)
    cell = Cell(mesh, 1)

    assert round(cell.distance(Point(-1.0, -1.0)) - numpy.sqrt(2), 7) == 0
    assert round(cell.distance(Point(-1.0, 0.5)) - 1, 7) == 0
    assert round(cell.distance(Point(0.5, 0.5)) - 0.0, 7) == 0
示例#13
0
def test_distance_tetrahedron():

    mesh = UnitCubeMesh(MPI.comm_self, 1, 1, 1)
    cell = Cell(mesh, 5)

    assert round(cell.distance(Point(-1.0, -1.0, -1.0)) - numpy.sqrt(3),
                 7) == 0
    assert round(cell.distance(Point(-1.0, 0.5, 0.5)) - 1, 7) == 0
    assert round(cell.distance(Point(0.5, 0.5, 0.5)) - 0.0, 7) == 0
示例#14
0
    def __init__(self, u, locations, t0=0.0, record=''):
        # The idea here is that u(x) means: search for cell containing x,
        # evaluate the basis functions of that element at x, restrict
        # the coef vector of u to the cell. Of these 3 steps the first
        # two don't change. So we cache them
        # Check the scalar assumption
        assert u.value_rank() == 0 and u.value_size() == 1

        # Locate each point
        mesh = u.function_space().mesh()
        limit = mesh.num_entities_global(mesh.topology().dim())
        bbox_tree = mesh.bounding_box_tree()

        cells_for_x = [None] * len(locations)
        for i, x in enumerate(locations):
            cell = bbox_tree.compute_first_entity_collision(Point(*x))
            if -1 < cell < limit:
                cells_for_x[i] = cell
        # Ignore the cells that are not in the mesh. Note that we don't
        # care if a node is found in several cells -l think CPU interface
        xs_cells = filter(lambda (xi, c): c is not None,
                          zip(locations, cells_for_x))

        V = u.function_space()
        element = V.dolfin_element()
        coefficients = np.zeros(element.space_dimension())
        # I build a series of functions bound to right variables that
        # when called compute the value at x
        evals = []
        locations = []
        for x, ci in xs_cells:
            basis_matrix = np.zeros(element.space_dimension())

            cell = Cell(mesh, ci)
            vertex_coords, orientation = cell.get_vertex_coordinates(
            ), cell.orientation()
            # Eval the basis once
            element.evaluate_basis_all(basis_matrix, x, vertex_coords,
                                       orientation)

            def foo(A=basis_matrix, cell=cell, vc=vertex_coords):
                # Restrict for each call using the bound cell, vc ...
                u.restrict(coefficients, element, cell, vc, cell)
                # A here is bound to the right basis_matri
                return np.dot(A, coefficients)

            evals.append(foo)
            locations.append(x)

        self.probes = evals
        self.locations = locations
        self.rank = MPI.rank(mesh.mpi_comm())
        self.data = []
        self.record = record
        # Make the initial record
        self.probe(t=t0)
示例#15
0
def test_volume_quadrilateralR3(coordinates):

    mesh = Mesh(MPI.comm_world, CellType.Type.quadrilateral,
                numpy.array(coordinates, dtype=numpy.float64),
                numpy.array([[0, 1, 2, 3]], dtype=numpy.int32), [],
                cpp.mesh.GhostMode.none)

    mesh.init()
    cell = Cell(mesh, 0)

    assert cell.volume() == 1.0
示例#16
0
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
示例#17
0
    def __init__(self, V, **kwargs):
        super().__init__(self, element=V.ufl_element(), **kwargs)
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())
示例#18
0
def test_save_and_read_mesh_value_collection(tempdir):
    ndiv = 2
    filename = os.path.join(tempdir, "mesh_value_collection.h5")
    mesh = UnitCubeMesh(MPI.comm_world, ndiv, ndiv, ndiv)

    def point2list(p):
        return [p[0], p[1], p[2]]

    # write to file
    with HDF5File(mesh.mpi_comm(), filename, 'w') as f:
        for dim in range(mesh.topology.dim):
            mvc = MeshValueCollection("size_t", mesh, dim)
            mesh.create_entities(dim)
            for e in MeshEntities(mesh, dim):
                # this can be easily computed to the check the value
                val = int(ndiv * sum(point2list(e.midpoint()))) + 1
                mvc.set_value(e.index(), val)
            f.write(mvc, "/mesh_value_collection_{}".format(dim))

    # read from file
    with HDF5File(mesh.mpi_comm(), filename, 'r') as f:
        for dim in range(mesh.topology.dim):
            mvc = f.read_mvc_size_t(mesh,
                                    "/mesh_value_collection_{}".format(dim))
            # check the values
            for (cell, lidx), val in mvc.values().items():
                eidx = Cell(mesh, cell).entities(dim)[lidx]
                mid = point2list(MeshEntity(mesh, dim, eidx).midpoint())
                assert val == int(ndiv * sum(mid)) + 1
示例#19
0
def convert_vector_nodes_to_cells(root_dir, mesh, V):
    # Extract constants
    total_cell_num = mesh.num_cells()
    dofs_num_per_cell = len(V.dofmap().cell_dofs(0))
    # Pre-define empty arrays
    dof_index_to_cell_table = np.empty((total_cell_num, dofs_num_per_cell), dtype=np.uint32)
    cell_volumes = np.empty(total_cell_num)
    cell_coordinates = np.empty((total_cell_num, 3))
    # Generate cell-to-dof-indices & cell-to-volume matching table & cell coordinates
    file_path1 = root_dir + 'dof_index_to_cell_table.npy'
    file_path2 = root_dir + 'cell_volumes.npy'
    file_path3 = root_dir + 'cell_coordinates.npy'
    if (os.path.isfile(file_path1)) & (os.path.isfile(file_path2)) & (os.path.isfile(file_path3)):
        dof_index_to_cell_table = np.load(file_path1)
        cell_volumes = np.load(file_path2)
        cell_coordinates = np.load(file_path3)
    else:
        print("No cell information file detected")
        print(" ==> Creating new cell information")
        for cell_num in range(total_cell_num):
            dof_index_to_cell_table[cell_num] = V.dofmap().cell_dofs(cell_num)
            cell_volumes[cell_num] = Cell(mesh, cell_num).volume()
            cell_coordinates[cell_num] = MeshEntity(mesh, 3, cell_num).midpoint().array()
        np.save(file_path1, dof_index_to_cell_table)
        np.save(file_path2, cell_volumes)
        np.save(file_path3, cell_coordinates)
    return (cell_volumes, cell_coordinates, dof_index_to_cell_table)
示例#20
0
def find_low(mesh, V, Ause):

    V2dm = V.dofmap()
    cq2 = MeshQuality.radius_ratios(mesh)
    cq = cq2.array()

    indices = np.where(cq < 0.1)[0]

    dof_set = []
    cell_set = []
    for i in indices:
        cell = Cell(mesh, i)
        for v in vertices(cell):
            for c in cells(v):
                cell_set += [c.index()]
                dof_set.extend(V2dm.cell_dofs(c.index()))

    bad_set = list(set(dof_set))
    bad_cells = list(set(cell_set))

    # print('BAD CELLS=', bad_cells)
    # print(len(bad_cells))
    # print('BAD DOFS=', bad_dofs)
    # print(len(bad_dofs))

    # check redundancy
    re_dofs = []
    for d1 in bad_set:
        for d2 in bad_set:
            if Ause[d1, d2] != 0:
                re_dofs.append(d2)

    bad_dofs = list(set(re_dofs))

    return bad_dofs
示例#21
0
def ExtractPoints(structure):

    if isinstance(structure, df.Mesh):
        mesh = structure
        dim = mesh.num_cells()
        dofmap = None
    elif isinstance(structure, df.FunctionSpace):
        ufl = structure.ufl_element()
        if ufl.degree() != 0 or ufl.family() != 'Discontinuous Lagrange':
            raise ValueError
        mesh = structure.mesh()
        dim = structure.dim()
        dofmap = structure.dofmap()
    else:
        raise ValueError

    Cells = [Cell(mesh, i) for i in range(mesh.num_cells())]

    topological_dim = mesh.geometry().dim()

    X = np.zeros((dim, topological_dim))

    for cell in Cells:

        if dofmap is not None:
            index = dofmap.cell_dofs(cell.index())
        else:
            index = cell.index()

        X[index, :] = cell.midpoint().array()[0:topological_dim]

    return X
示例#22
0
    def _get_changes(self, cell_index):
        'Get identifiers for positions and labels that were changed in cell.'
        changed_positions = []
        changed_labels = []
        order = self.order
        first_dof = self.first_dof

        for i, j in enumerate(self.component):
            cell = Cell(self.mesh, cell_index)
            dofs = self.dofmaps[j].cell_dofs(cell_index)
            dofs_x = self.dofmaps[j].tabulate_coordinates(cell)
            for dof, dof_x in zip(dofs, dofs_x):
                dof_x_str = x_to_str(dof_x)
                # Append to change if dof position was not plotted yet
                if not (dof_x_str in self.positions):
                    self.positions[dof_x_str] = dof_x.tolist()
                    changed_positions.append(dof_x_str)

                dof = dof if order == 'global' else dof - first_dof
                # If dof label was no created yet create structure for label
                if not (dof_x_str in self.labels):
                    self.labels[dof_x_str] =\
                        [[] for k in range(len(self.dofmaps))]
                    self.labels[dof_x_str][i].append(dof)
                    changed_labels.append(dof_x_str)
                else:
                    # We have dofmaps that have dofs in shared position
                    # Structure created so just append
                    if not (dof in self.labels[dof_x_str][i]):
                        self.labels[dof_x_str][i].append(dof)
                        changed_labels.append(dof_x_str)

        # Make unique
        changed_labels = set(changed_labels)
        return changed_positions, changed_labels
示例#23
0
def test_local_assembler_1D():
    mesh = UnitIntervalMesh(MPI.comm_world, 20)
    V = FunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)
    c = Cell(mesh, 0)

    a_scalar = 1.0 * dx(domain=mesh)
    a_vector = v * dx
    a_matrix = u * v * dx

    A_scalar = assemble_local(a_scalar, c)
    A_vector = assemble_local(a_vector, c)
    A_matrix = assemble_local(a_matrix, c)

    assert isinstance(A_scalar, float)
    assert numpy.isclose(A_scalar, 0.05)

    assert isinstance(A_vector, numpy.ndarray)
    assert A_vector.shape == (2,)
    assert numpy.isclose(A_vector[0], 0.025)
    assert numpy.isclose(A_vector[1], 0.025)

    assert isinstance(A_matrix, numpy.ndarray)
    assert A_matrix.shape == (2, 2)
    assert numpy.isclose(A_matrix[0, 0], 1 / 60)
    assert numpy.isclose(A_matrix[0, 1], 1 / 120)
    assert numpy.isclose(A_matrix[1, 0], 1 / 120)
    assert numpy.isclose(A_matrix[1, 1], 1 / 60)
示例#24
0
class FEBasisFunction(object):
    '''Evaluator of dof of V on functions'''
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        shape = V.ufl_element().value_shape()
        degree = V.ufl_element().degree()

        # A fake instanc to talk to with the world
        adapter = type('MiroHack',
                       (Expression, ),
                       {'value_shape': lambda self_, : shape,
                        'eval': lambda self_, values, x: self.eval(values, x)})
        self.__adapter = adapter(degree=degree)

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())

    @property
    def dof(self):
        return self.__dof

    @dof.setter
    def dof(self, value):
        assert value < self.elm.space_dimension()
        self.__dof = value
    
    @property
    def cell(self):
        return self.__cell

    @cell.setter
    def cell(self, value):
        cell_ = Cell(self.mesh, value)
        self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(cell_)
        self.__cell = cell_

    def eval(self, values, x):
        self.elm.evaluate_basis(self.dof,
                                values[:], 
                                x,
                                self.__cell_vertex_x,
                                self.__cell_orientation)

    def __call__(self, x):
        self.eval(self.__values, x)
        return 1*self.__values

    def as_expression(self):
        return self.__adapter
示例#25
0
class FEBasisFunction(object):
    '''Evaluator of dof of V on functions'''
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        shape = V.ufl_element().value_shape()
        degree = V.ufl_element().degree()

        # A fake instanc to talk to with the world
        adapter = type(
            'MiroHack', (Expression, ), {
                'value_shape': lambda self_, : shape,
                'eval': lambda self_, values, x: self.eval(values, x)
            })
        self.__adapter = adapter(degree=degree)

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry(
        ).dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())

    @property
    def dof(self):
        return self.__dof

    @dof.setter
    def dof(self, value):
        assert value < self.elm.space_dimension()
        self.__dof = value

    @property
    def cell(self):
        return self.__cell

    @cell.setter
    def cell(self, value):
        cell_ = Cell(self.mesh, value)
        self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(cell_)
        self.__cell = cell_

    def eval(self, values, x):
        self.elm.evaluate_basis(self.dof, values[:], x, self.__cell_vertex_x,
                                self.__cell_orientation)

    def __call__(self, x):
        self.eval(self.__values, x)
        return 1 * self.__values

    def as_expression(self):
        return self.__adapter
示例#26
0
def test_volume_quadrilateral_coplanarity_check_2(scaling):

    with pytest.raises(RuntimeError) as error:
        # Unit square cell scaled down by 'scaling' and the first
        # vertex is distorted so that the vertices are clearly non
        # coplanar
        mesh = Mesh(
            MPI.comm_world, CellType.Type.quadrilateral,
            numpy.array([[1.0, 0.5, 0.6], [0.0, scaling, 0.0],
                         [0.0, 0.0, scaling], [0.0, 1.0, 1.0]],
                        dtype=numpy.float64),
            numpy.array([[0, 1, 2, 3]], dtype=numpy.int32), [],
            cpp.mesh.GhostMode.none)
        mesh.init()
        cell = Cell(mesh, 0)
        cell.volume()

    assert "are not coplanar" in str(error.value)
示例#27
0
def point_trace_matrix(V, TV, x0):
    '''
    Let u in V; u = ck phi_k then u(x0) \in TV = ck phi_k(x0). So this 
    is a 1 by dim(V) matrix where the column values are phi_k(x0).
    '''
    mesh = V.mesh()
    tree = mesh.bounding_box_tree()
    cell = tree.compute_first_entity_collision(Point(*x0))
    assert cell < mesh.num_cells()

    # Cell for restriction
    Vcell = Cell(mesh, cell)
    vertex_coordinates = Vcell.get_vertex_coordinates()
    cell_orientation = Vcell.orientation()
    x0 = np.fromiter(x0, dtype=float)

    # Columns - get all components at once
    all_dofs = V.dofmap().cell_dofs(cell).tolist()
    Vel = V.element()
    value_size = V.ufl_element().value_size()
    basis_values = np.zeros(V.element().space_dimension() * value_size)

    Vel.evaluate_basis_all(basis_values, x0, vertex_coordinates,
                           cell_orientation)

    with petsc_serial_matrix(TV, V) as mat:

        # Scalar gets all
        if value_size == 1:
            component_dofs = lambda component: V.dofmap().cell_dofs(cell)
        # Slices
        else:
            component_dofs = lambda component: V.sub(component).dofmap(
            ).cell_dofs(cell)

        for row in map(int, TV.dofmap().cell_dofs(cell)):  # R^n components
            sub_dofs = component_dofs(row)
            sub_dofs_local = [all_dofs.index(dof) for dof in sub_dofs]
            print row, sub_dofs, sub_dofs_local, basis_values[sub_dofs_local]

            mat.setValues([row], sub_dofs, basis_values[sub_dofs_local],
                          PETSc.InsertMode.INSERT_VALUES)
    return mat
示例#28
0
def write_fenics_file(dim, ofilename):
    ofile  = File(ofilename + '.xml')
    mesh = Mesh()
    editor = MeshEditor()
    editor.open(mesh, dim, dim)
    editor.init_vertices(nodes.shape[1])
    editor.init_cells(len(cell_map))    
    for i in range(nodes.shape[1]):
        if dim == 2:
            editor.add_vertex(i, nodes[0, i], nodes[1, i])
        else:
            editor.add_vertex(i, nodes[0, i], nodes[1, i], nodes[2, i])
            
    for i in range(1, len(cell_map)+1):
        if dim == 2:
            editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1)
        else:
            editor.add_cell(i-1, cell_map[i][0]-1, cell_map[i][1]-1, cell_map[i][2]-1, cell_map[i][3]-1)
    
    mesh.order()
    mvc = mesh.domains().markers(dim-1)
    for zone, cells in boundary_cells.iteritems():
        for cell, nds in cells.iteritems():
            dolfin_cell = Cell(mesh, cell-1)
            nodes_of_cell = dolfin_cell.entities(0)
            #print cell
            #print nodes_of_cell
            nodes_of_face = nds - 1
            #print nodes_of_face
            for jj, ff in enumerate(facets(dolfin_cell)):
                facet_nodes = ff.entities(0)
                #print facet_nodes
                if all(map(lambda x: x in nodes_of_face, facet_nodes)):
                    local_index = jj
                    break
            mvc.set_value(cell-1, local_index, zone)
        
    ofile << mesh        
    from dolfin import plot
    plot(mesh, interactive=True)
    print 'Finished writing FEniCS mesh\n'
示例#29
0
def point_trace_matrix(V, TV, x0):
    '''
    Let u in V; u = ck phi_k then u(x0) \in TV = ck phi_k(x0). So this 
    is a 1 by dim(V) matrix where the column values are phi_k(x0).
    '''
    mesh = V.mesh()
    tree = mesh.bounding_box_tree()
    cell = tree.compute_first_entity_collision(Point(*x0))
    assert cell < mesh.num_cells()

    # Cell for restriction
    Vcell = Cell(mesh, cell)
    vertex_coordinates = Vcell.get_vertex_coordinates()
    cell_orientation = Vcell.orientation()
    x0 = np.fromiter(x0, dtype=float)

    # Columns - get all components at once
    all_dofs = V.dofmap().cell_dofs(cell).tolist()
    Vel = V.element()
    value_size = V.ufl_element().value_size()
    basis_values = np.zeros(V.element().space_dimension()*value_size)

    Vel.evaluate_basis_all(basis_values, x0, vertex_coordinates, cell_orientation)

    with petsc_serial_matrix(TV, V) as mat:

        # Scalar gets all
        if value_size == 1:
            component_dofs = lambda component: V.dofmap().cell_dofs(cell)
        # Slices
        else:
            component_dofs = lambda component: V.sub(component).dofmap().cell_dofs(cell)
        
        for row in map(int, TV.dofmap().cell_dofs(cell)):  # R^n components
            sub_dofs = component_dofs(row)
            sub_dofs_local = [all_dofs.index(dof) for dof in sub_dofs]
            print row, sub_dofs, sub_dofs_local, basis_values[sub_dofs_local]
            
            mat.setValues([row], sub_dofs, basis_values[sub_dofs_local],
                          PETSc.InsertMode.INSERT_VALUES)
    return mat
示例#30
0
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
示例#31
0
def build_grad_matrices(V, points):
    """Build the sparse m-by-n matrices that map a coefficient set for a function in V
    to the values of dx and dy at a number m of points.
    """
    # See <https://www.allanswered.com/post/lkbkm/#zxqgk>
    mesh = V.mesh()

    bbt = BoundingBoxTree()
    bbt.build(mesh)
    dofmap = V.dofmap()
    el = V.element()
    rows = []
    cols = []
    datax = []
    datay = []
    for i, xy in enumerate(points):
        cell_id = bbt.compute_first_entity_collision(Point(*xy))
        cell = Cell(mesh, cell_id)
        coordinate_dofs = cell.get_vertex_coordinates()

        rows.append([i, i, i])
        cols.append(dofmap.cell_dofs(cell_id))

        v = el.evaluate_basis_derivatives_all(1, xy, coordinate_dofs, cell_id)
        v = v.reshape(3, 2)
        datax.append(v[:, 0])
        datay.append(v[:, 1])

    rows = numpy.concatenate(rows)
    cols = numpy.concatenate(cols)
    datax = numpy.concatenate(datax)
    datay = numpy.concatenate(datay)

    m = len(points)
    n = V.dim()
    dx_matrix = sparse.csr_matrix((datax, (rows, cols)), shape=(m, n))
    dy_matrix = sparse.csr_matrix((datay, (rows, cols)), shape=(m, n))
    return dx_matrix, dy_matrix
示例#32
0
def test_pointsource_vector(mesh):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector that isn't placed at a node for 1D, 2D and
    3D. Global points given to constructor from rank 0 processor

    """

    cell = Cell(mesh, 0)
    point = cell.midpoint()
    rank = MPI.rank(mesh.mpi_comm())

    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0) * v * dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0) == 0
示例#33
0
def test_pointsource_vector(mesh):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector that isn't placed at a node for 1D, 2D and
    3D. Global points given to constructor from rank 0 processor

    """

    cell = Cell(mesh, 0)
    point = cell.midpoint()
    rank = MPI.rank(mesh.mpi_comm())

    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0)*v*dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0) == 0
示例#34
0
class FEBasisFunction(UserExpression):
    '''Evaluator of dof of V on functions'''
    def __init__(self, V, **kwargs):
        super().__init__(self, element=V.ufl_element(), **kwargs)
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())

    @property
    def dof(self):
        return self.__dof

    @dof.setter
    def dof(self, value):
        assert value < self.elm.space_dimension()
        self.__dof = value
    
    @property
    def cell(self):
        return self.__cell

    @cell.setter
    def cell(self, value):
        cell_ = Cell(self.mesh, value)
        self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(cell_)
        self.__cell = cell_

    def eval_cell(self, values, x, cell):
        values[:] = self.elm.evaluate_basis(self.dof,
                                            x,
                                            self.__cell_vertex_x,
                                            self.__cell_orientation)

    def __call__(self, x):
        self.eval(self.__values, x)
        return 1*self.__values
示例#35
0
class DegreeOfFreedom(object):
    '''Evaluator of dof of V on functions'''
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0

    @property
    def dof(self):
        return self.__dof

    @dof.setter
    def dof(self, value):
        assert value < self.elm.space_dimension()
        self.__dof = value
    
    @property
    def cell(self):
        return self.__cell

    @cell.setter
    def cell(self, value):
        cell_ = Cell(self.mesh, value)
        self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(cell_)
        self.__cell = cell_

    def eval(self, f):
        return self.elm.evaluate_dofs(f,
                                      self.__cell_vertex_x,
                                      self.__cell_orientation,
                                      self.__cell)[self.dof]

    def eval_dofs(self, f):
        return self.elm.evaluate_dofs(f,
                                      self.__cell_vertex_x,
                                      self.__cell_orientation,
                                      self.__cell)
示例#36
0
    def test_simplex(self):
        print('\n== Testing DOFs ====')

        for dim, p in itertools.product([2, 3], range(1, 6)):
            print('dim={}; p={}'.format(dim, p))
            mesh = get_reference_element(dim)
            W = FunctionSpace(mesh, "DG", p)
            cell = Cell(mesh, 0)
            dofs = W.element().tabulate_dof_coordinates(cell)
            dofs2 = get_dof_coordinates(dim, pol_order=p)
            dofs = dofs[np.lexsort(dofs.T)]
            dofs2 = dofs2[np.lexsort(dofs2.T)]
            self.assertAlmostEqual(0,
                                   np.linalg.norm(dofs - dofs2),
                                   delta=1e-14)
            self.assertAlmostEqual(W.element().space_dimension(),
                                   dimP(dim, p),
                                   delta=1e-13)
        print('...ok')
示例#37
0
def test_issue_568():
    mesh = UnitSquareMesh(MPI.comm_self, 4, 4)
    cell = Cell(mesh, 0)

    # This no longer fails because serial mesh now is building facets, using
    # same pipeline as parallel.

    # Should throw an error, not just segfault (only works in DEBUG mode!)
    with pytest.raises(RuntimeError):
        cell.facet_area(0)

    # Should work after initializing the connectivity
    mesh.init(2, 1)
    cell.facet_area(0)
示例#38
0
class DegreeOfFreedom(object):
    '''Evaluator of dof of V on functions'''
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0

    @property
    def dof(self):
        return self.__dof

    @dof.setter
    def dof(self, value):
        assert value < self.elm.space_dimension()
        self.__dof = value
    
    @property
    def cell(self):
        return self.__cell

    @cell.setter
    def cell(self, value):
        cell_ = Cell(self.mesh, value)
        self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(cell_)
        self.__cell = cell_

    def eval(self, f):
        return self.elm.evaluate_dof(self.dof,
                                     f.as_expression() if isinstance(f, FEBasisFunction) else f,
                                     self.__cell_vertex_x,
                                     self.__cell_orientation,
                                     self.__cell)
示例#39
0
    def __init__(self, V):
        self.elm = V.element()
        self.mesh = V.mesh()

        shape = V.ufl_element().value_shape()
        degree = V.ufl_element().degree()

        # A fake instanc to talk to with the world
        adapter = type('MiroHack',
                       (Expression, ),
                       {'value_shape': lambda self_, : shape,
                        'eval': lambda self_, values, x: self.eval(values, x)})
        self.__adapter = adapter(degree=degree)

        is_1d_in_3d = self.mesh.topology().dim() == 1 and self.mesh.geometry().dim() == 3
        self.orient_cell = cell_orientation(is_1d_in_3d)

        # Allocs
        self.__cell = Cell(self.mesh, 0)
        self.__cell_vertex_x = self.__cell.get_vertex_coordinates()
        self.__cell_orientation = self.orient_cell(self.__cell)
        self.__dof = 0
        self.__values = np.zeros(V.ufl_element().value_size())
示例#40
0
    def _single_mesh_entity_plot(self, cell_index, tdim):
        'Plot labels of mesh entities of topological dim. that are in cell.'
        # Compute cell->entity connectivity unless cell-cell. Don't need patch
        if self.tdim == tdim:
            entity_indices = [cell_index]
        else:
            entity_indices = Cell(self.mesh, cell_index).entities(tdim)

        color = self.mesh_entity_colors[tdim]
        labels = self.mesh_entity_labels[tdim]
        # Loop through entities of the cell
        for entity_index in entity_indices:
            entity = MeshEntity(self.mesh, tdim, entity_index)
            # Midpoint is label location
            x = entity.midpoint()
            x = [x[i] for i in range(self.gdim)]
            if (self.order == 'global') and self.mpi_size > 1:
                args = x + [str(entity.global_index())]
            else:
                args = x + [str(entity_index)]
            # Create new label if entitiy not labeled already
            if not (entity_index in labels):
                labels[entity_index] = self.axes.text(*args, color=color)
示例#41
0
def test_ghost_connectivities(mode):
    # Ghosted mesh
    meshG = UnitSquareMesh(MPI.comm_world, 4, 4, ghost_mode=mode)
    meshG.init(1, 2)

    # Reference mesh, not ghosted, not parallel
    meshR = UnitSquareMesh(MPI.comm_self,
                           4,
                           4,
                           ghost_mode=cpp.mesh.GhostMode.none)
    meshR.init(1, 2)

    # Create reference mapping from facet midpoint to cell midpoint
    reference = {}
    for facet in Facets(meshR):
        fidx = facet.index()
        facet_mp = tuple(facet.midpoint()[:])
        reference[facet_mp] = []
        for cidx in meshR.topology.connectivity(1, 2)(fidx):
            cell = Cell(meshR, cidx)
            cell_mp = tuple(cell.midpoint()[:])
            reference[facet_mp].append(cell_mp)

    # Loop through ghosted mesh and check connectivities
    allowable_cell_indices = [
        c.index() for c in Cells(meshG, cpp.mesh.MeshRangeType.ALL)
    ]
    for facet in Facets(meshG, cpp.mesh.MeshRangeType.REGULAR):
        fidx = facet.index()
        facet_mp = tuple(facet.midpoint()[:])
        assert facet_mp in reference

        for cidx in meshG.topology.connectivity(1, 2)(fidx):
            assert cidx in allowable_cell_indices
            cell = Cell(meshG, cidx)
            cell_mp = tuple(cell.midpoint()[:])
            assert cell_mp in reference[facet_mp]
示例#42
0
 def cell(self, value):
     cell_ = Cell(self.mesh, value)
     self.__cell_vertex_x[:] = cell_.get_vertex_coordinates()
     self.__cell_orientation = self.orient_cell(cell_)
     self.__cell = cell_
示例#43
0
def cylinder_average_matrix(V, TV, radius, quad_degree):
    '''Averaging matrix'''
    mesh = V.mesh()
    line_mesh = TV.mesh()
    # We are going to perform the integration with Gauss quadrature at
    # the end (PI u)(x):
    # A cell of mesh (an edge) defines a normal vector. Let P be the plane
    # that is defined by the normal vector n and some point x on Gamma. Let L
    # be the circle that is the intersect of P and S. The value of q (in Q) at x
    # is defined as
    #
    #                    q(x) = (1/|L|)*\int_{L}g(x)*dL
    #
    # which simplifies to g(x) = (1/(2*pi*R))*\int_{-pi}^{pi}u(L)*R*d(theta) and
    # or                       = (1/2) * \int_{-1}^{1} u (L(pi*s)) * ds
    # This can be integrated no problemo once we figure out L. To this end, let
    # t_1 and t_2 be two unit mutually orthogonal vectors that are orthogonal to
    # n. Then L(pi*s) = p + R*t_1*cos(pi*s) + R*t_2*sin(pi*s) can be seen to be
    # such that i) |x-p| = R and ii) x.n = 0 [i.e. this the suitable
    # parametrization]
    
    # Clearly we can scale the weights as well as precompute
    # cos and sin terms.
    xq, wq = leggauss(quad_degree)
    wq *= 0.5
    cos_xq = np.cos(np.pi*xq).reshape((-1, 1))
    sin_xq = np.sin(np.pi*xq).reshape((-1, 1))

    if is_number(radius):
         radius = lambda x, radius=radius: radius 

    mesh_x = TV.mesh().coordinates()
    # The idea for point evaluation/computing dofs of TV is to minimize
    # the number of evaluation. I mean a vector dof if done naively would
    # have to evaluate at same x number of component times.
    value_size = TV.ufl_element().value_size()

    # Eval at points will require serch
    tree = mesh.bounding_box_tree()
    limit = mesh.num_cells()

    TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1))
    TV_dm = TV.dofmap()
    V_dm = V.dofmap()
    # For non scalar we plan to make compoenents by shift
    if value_size > 1:
        TV_dm = TV.sub(0).dofmap()

    Vel = V.element()               
    basis_values = np.zeros(V.element().space_dimension()*value_size)
    with petsc_serial_matrix(TV, V) as mat:

        for line_cell in cells(line_mesh):
            # Get the tangent => orthogonal tangent vectors

            v0, v1 = mesh_x[line_cell.entities(0)]
            n = v0 - v1

            t1 = np.array([n[1]-n[2], n[2]-n[0], n[0]-n[1]])
    
            t2 = np.cross(n, t1)
            t1 /= np.linalg.norm(t1)
            t2 = t2/np.linalg.norm(t2)

            # The idea is now to minimize the point evaluation
            scalar_dofs = TV_dm.cell_dofs(line_cell.index())
            scalar_dofs_x = TV_coordinates[scalar_dofs]
            for scalar_row, avg_point in zip(scalar_dofs, scalar_dofs_x):
                # Get radius and integration points
                rad = radius(avg_point)
         
                integration_points = avg_point + rad*t1*sin_xq + rad*t2*cos_xq

                data = {}
                for index, ip in enumerate(integration_points):
                    c = tree.compute_first_entity_collision(Point(*ip))
                    if c >= limit: continue

                    Vcell = Cell(mesh, c)
                    vertex_coordinates = Vcell.get_vertex_coordinates()
                    cell_orientation = Vcell.orientation()
                    Vel.evaluate_basis_all(basis_values, ip, vertex_coordinates, cell_orientation)

                    cols_ip = V_dm.cell_dofs(c)
                    values_ip = basis_values*wq[index]
                    # Add
                    for col, value in zip(cols_ip, values_ip.reshape((-1, value_size))):
                        if col in data:
                            data[col] += value
                        else:
                            data[col] = value
                            
                # The thing now that with data we can assign to several
                # rows of the matrix
                column_indices = np.array(data.keys(), dtype='int32')
                for shift in range(value_size):
                    row = scalar_row + shift
                    column_values = np.array([data[col][shift] for col in column_indices])
                    mat.setValues([row], column_indices, column_values, PETSc.InsertMode.INSERT_VALUES)
            # On to next avg point
        # On to next cell
    return PETScMatrix(mat)
示例#44
0
def sphere_average_matrix(V, TV, radius, quad_degree):
    '''Averaging matrix over the sphere'''
    mesh = V.mesh()
    line_mesh = TV.mesh()
    # Lebedev below need off degrees
    if quad_degree % 2 == 0: quad_degree += 1
    # NOTE: this is a dependency
    from quadpy.sphere import Lebedev

    integrator = Lebedev(quad_degree)
    xq = integrator.points
    wq = integrator.weights
    
    if is_number(radius):
         radius = lambda x, radius=radius: radius 

    mesh_x = TV.mesh().coordinates()
    # The idea for point evaluation/computing dofs of TV is to minimize
    # the number of evaluation. I mean a vector dof if done naively would
    # have to evaluate at same x number of component times.
    value_size = TV.ufl_element().value_size()

    # Eval at points will require serch
    tree = mesh.bounding_box_tree()
    limit = mesh.num_cells()

    TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1))
    TV_dm = TV.dofmap()
    V_dm = V.dofmap()
    # For non scalar we plan to make compoenents by shift
    if value_size > 1:
        TV_dm = TV.sub(0).dofmap()

    Vel = V.element()               
    basis_values = np.zeros(V.element().space_dimension()*value_size)
    with petsc_serial_matrix(TV, V) as mat:

        for line_cell in cells(line_mesh):
            # The idea is now to minimize the point evaluation
            scalar_dofs = TV_dm.cell_dofs(line_cell.index())
            scalar_dofs_x = TV_coordinates[scalar_dofs]
            for scalar_row, avg_point in zip(scalar_dofs, scalar_dofs_x):
                # Get radius and integration points
                rad = radius(avg_point)
                # Scale and shift the unit sphere to the point
                integration_points = xq*rad + avg_point

                data = {}
                for index, ip in enumerate(integration_points):
                    c = tree.compute_first_entity_collision(Point(*ip))
                    if c >= limit: continue

                    Vcell = Cell(mesh, c)
                    vertex_coordinates = Vcell.get_vertex_coordinates()
                    cell_orientation = Vcell.orientation()
                    Vel.evaluate_basis_all(basis_values, ip, vertex_coordinates, cell_orientation)

                    cols_ip = V_dm.cell_dofs(c)
                    values_ip = basis_values*wq[index]
                    # Add
                    for col, value in zip(cols_ip, values_ip.reshape((-1, value_size))):
                        if col in data:
                            data[col] += value
                        else:
                            data[col] = value
                            
                # The thing now that with data we can assign to several
                # rows of the matrix
                column_indices = np.array(data.keys(), dtype='int32')
                for shift in range(value_size):
                    row = scalar_row + shift
                    column_values = np.array([data[col][shift] for col in column_indices])
                    mat.setValues([row], column_indices, column_values, PETSc.InsertMode.INSERT_VALUES)
            # On to next avg point
        # On to next cell
    return PETScMatrix(mat)
示例#45
0
def trace_3d1d_matrix(V, TV, reduced_mesh):
    '''Trace from 3d to 1d. Makes sense only for CG space'''
    assert reduced_mesh.id() == TV.mesh().id()
    assert V.ufl_element().family() == 'Lagrange'
    
    mesh = V.mesh()
    line_mesh = TV.mesh()
    
    # The idea for point evaluation/computing dofs of TV is to minimize
    # the number of evaluation. I mean a vector dof if done naively would
    # have to evaluate at same x number of component times.
    value_size = TV.ufl_element().value_size()

    # We use the map to get (1d cell -> [3d edge) -> 3d cell]
    if hasattr(reduced_mesh, 'parent_entity_map'):
        # ( )
        mapping = reduced_mesh.parent_entity_map[mesh.id()][1]
        # [ ]
        mesh.init(1)
        mesh.init(1, 3)
        e2c = mesh.topology()(1, 3)
        # From 1d cell (by index)
        get_cell3d = lambda c, d1d3=mapping, d3d3=e2c: d3d3(d1d3[c.index()])[0]
    # Tree collision by midpoint
    else:
        tree = mesh.bounding_box_tree()
        limit = mesh.num_cells()

        get_cell3d = lambda c, tree=tree, bound=limit: (
            lambda index: index if index<bound else None
        )(tree.compute_first_entity_collision(c.midpoint()))
  
    TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1))
    TV_dm = TV.dofmap()
    V_dm = V.dofmap()
    # For non scalar we plan to make compoenents by shift
    if value_size > 1:
        TV_dm = TV.sub(0).dofmap()

    Vel = V.element()               
    basis_values = np.zeros(V.element().space_dimension()*value_size)
    with petsc_serial_matrix(TV, V) as mat:

        for line_cell in cells(line_mesh):
            # Get the tangent => orthogonal tangent vectors
            # The idea is now to minimize the point evaluation
            scalar_dofs = TV_dm.cell_dofs(line_cell.index())
            scalar_dofs_x = TV_coordinates[scalar_dofs]

            # Let's get a 3d cell to use for getting the V values
            # CG assumption allows taking any
            tet_cell = get_cell3d(line_cell)
            if tet_cell is None: continue
            
            Vcell = Cell(mesh, tet_cell)
            vertex_coordinates = Vcell.get_vertex_coordinates()
            cell_orientation = 0
            # Columns are determined by V cell! I guess the sparsity
            # could be improved if for x_dofs of TV only x_dofs of V
            # were considered
            column_indices = np.array(V_dm.cell_dofs(tet_cell), dtype='int32')

            for scalar_row, avg_point in zip(scalar_dofs, scalar_dofs_x):
                # 3d at point
                Vel.evaluate_basis_all(basis_values, avg_point, vertex_coordinates, cell_orientation)
                # The thing now is that with data we can assign to several
                # rows of the matrix. Shift determines the (x, y, ... ) or
                # (xx, xy, yx, ...) component of Q
                data = basis_values.reshape((-1, value_size)).T
                for shift, column_values in enumerate(data):
                    row = scalar_row + shift
                    mat.setValues([row], column_indices, column_values, PETSc.InsertMode.INSERT_VALUES)
            # On to next avg point
        # On to next cell
    return PETScMatrix(mat)
示例#46
0
文件: Q4.py 项目: MiroK/eikonal
 def foo(cell_index): # get the midpoint as array
   cell = Cell(self.mesh, cell_index)
   midpoint = cell.midpoint()
   return [midpoint.x(), midpoint.y()]