Ejemplo n.º 1
0
    def get_coors(self, ig=None):
        """
        Get the coordinates of vertices of unique facets in group `ig`.

        Parameters
        ----------
        ig : int, optional
            The element group. If None, the coordinates for all groups
            are returned, filled with zeros at places of missing
            vertices, i.e. where facets having less then the full number
            of vertices (`n_v`) are.

        Returns
        -------
        coors : array
            The coordinates in an array of shape `(n_f, n_v, dim)`.
        uid : array
            The unique ids of facets in the order of `coors`.
        """
        cc = self.domain.get_mesh_coors()

        if ig is None:
            uid, ii = unique(self.uid_i, return_index=True)
            facets = self.facets[ii]
            aux = insert_strided_axis(facets, 2, cc.shape[1])
            coors = nm.where(aux >= 0, cc[facets], 0.0)

        else:
            uid_i = self.uid_i[self.indx[ig]]
            uid, ii = unique(uid_i, return_index=True)

            coors = cc[self.facets[ii, :self.n_fps[ig]]]

        return coors, uid
Ejemplo n.º 2
0
    def get_coors(self, ig=None):
        """
        Get the coordinates of vertices of unique facets in group `ig`.

        Parameters
        ----------
        ig : int, optional
            The element group. If None, the coordinates for all groups
            are returned, filled with zeros at places of missing
            vertices, i.e. where facets having less then the full number
            of vertices (`n_v`) are.

        Returns
        -------
        coors : array
            The coordinates in an array of shape `(n_f, n_v, dim)`.
        uid : array
            The unique ids of facets in the order of `coors`.
        """
        cc = self.domain.get_mesh_coors()

        if ig is None:
            uid, ii = unique(self.uid_i, return_index=True)
            facets = self.facets[ii]
            aux = insert_strided_axis(facets, 2, cc.shape[1])
            coors = nm.where(aux >= 0, cc[facets], 0.0)

        else:
            uid_i = self.uid_i[self.indx[ig]]
            uid, ii = unique(uid_i, return_index=True)

            coors = cc[self.facets[ii,:self.n_fps[ig]]]

        return coors, uid
Ejemplo n.º 3
0
 def treat_pbcs(self, master_equations):
     """
     Treat dofs with periodic BC.
     """
     umeq, indx = unique(master_equations, return_index=True)
     indx.sort()
     self.mtx = self.mtx[indx]
Ejemplo n.º 4
0
 def treat_pbcs(self, master_equations):
     """
     Treat dofs with periodic BC.
     """
     umeq, indx = unique(master_equations, return_index=True)
     indx.sort()
     self.mtx = self.mtx[indx]
Ejemplo n.º 5
0
    def get_coors(self, ig=0):
        """
        Get the coordinates of vertices of unique facets in group `ig`.

        Returns
        -------
        coors : array
            The coordinates in an array of shape `(n_f, n_v, dim)`.
        uid : array
            The unique ids of facets in the order of `coors`.
        """
        cc = self.domain.get_mesh_coors()

        uid_i = self.uid_i[self.indx[ig]]
        uid, ii = unique(uid_i, return_index=True)

        coors = cc[self.facets[ii,:self.n_fps[ig]]]

        return coors, uid
Ejemplo n.º 6
0
    def describe_dual_surface(self, surface):
        n_fa, n_edge = surface.n_fa, self.sgel.n_edge

        mesh_coors = self.mesh_coors

        # Face centres.
        fcoors = mesh_coors[surface.econn]
        centre_coors = nm.dot(self.bf.squeeze(), fcoors)

        surface_coors = mesh_coors[surface.nodes]

        dual_coors = nm.r_[surface_coors, centre_coors]
        coor_offset = surface.nodes.shape[0]

        # Normals in primary mesh nodes.
        nodal_normals = compute_nodal_normals(surface.nodes, self.region,
                                              self.field)

        ee = surface.leconn[:, self.sgel.edges].copy()
        edges_per_face = ee.copy()
        sh = edges_per_face.shape
        ee.shape = edges_per_face.shape = (sh[0] * sh[1], sh[2])
        edges_per_face.sort(axis=1)

        eo = nm.empty((sh[0] * sh[1], ), dtype=nm.object)
        eo[:] = [tuple(ii) for ii in edges_per_face]

        ueo, e_sort, e_id = unique(eo, return_index=True, return_inverse=True)
        ueo = edges_per_face[e_sort]

        # edge centre, edge point 1, face centre, edge point 2
        conn = nm.empty((n_edge * n_fa, 4), dtype=nm.int32)
        conn[:, 0] = e_id
        conn[:, 1] = ee[:, 0]
        conn[:,2] = nm.repeat(nm.arange(n_fa, dtype=nm.int32), n_edge) \
                    + coor_offset
        conn[:, 3] = ee[:, 1]

        # face centre, edge point 2, edge point 1
        tri_conn = nm.ascontiguousarray(conn[:, [2, 1, 3]])

        # Ensure orientation - outward normal.
        cc = dual_coors[tri_conn]
        v1 = cc[:, 1] - cc[:, 0]
        v2 = cc[:, 2] - cc[:, 0]

        normals = nm.cross(v1, v2)
        nn = nodal_normals[surface.leconn].sum(axis=1).repeat(n_edge, 0)
        centre_normals = (1.0 / surface.n_fp) * nn
        centre_normals /= la.norm_l2_along_axis(centre_normals)[:, None]
        dot = nm.sum(normals * centre_normals, axis=1)

        assert_((dot > 0.0).all())

        # Prepare mapping from reference triangle e_R to a
        # triangle within reference face e_D.
        gel = self.gel.surface_facet
        ref_coors = gel.coors
        ref_centre = nm.dot(self.bf.squeeze(), ref_coors)
        cc = nm.r_[ref_coors, ref_centre[None, :]]
        rconn = nm.empty((n_edge, 3), dtype=nm.int32)
        rconn[:, 0] = gel.n_vertex
        rconn[:, 1] = gel.edges[:, 0]
        rconn[:, 2] = gel.edges[:, 1]

        map_er_ed = VolumeMapping(cc, rconn, gel=gel)

        # Prepare mapping from reference triangle e_R to a
        # physical triangle e.
        map_er_e = SurfaceMapping(dual_coors, tri_conn, gel=gel)

        # Compute triangle basis (edge) vectors.
        nn = surface.nodes[ueo]
        edge_coors = mesh_coors[nn]

        edge_centre_coors = 0.5 * edge_coors.sum(axis=1)

        edge_normals = 0.5 * nodal_normals[ueo].sum(axis=1)

        edge_normals /= la.norm_l2_along_axis(edge_normals)[:, None]

        nn = surface.nodes[ueo]
        edge_dirs = edge_coors[:, 1] - edge_coors[:, 0]
        edge_dirs /= la.norm_l2_along_axis(edge_dirs)[:, None]

        edge_ortho = nm.cross(edge_normals, edge_dirs)
        edge_ortho /= la.norm_l2_along_axis(edge_ortho)[:, None]

        # Primary face - dual sub-faces map.
        # i-th row: indices to conn corresponding to sub-faces of i-th face.
        face_map = nm.arange(n_fa * n_edge, dtype=nm.int32)
        face_map.shape = (n_fa, n_edge)

        # The actual connectivity for assembling (unique nodes per master
        # faces).
        asm_conn = e_id[face_map]

        n_nod = ueo.shape[0]  # One node per unique edge.
        n_components = self.dim - 1

        dual_surface = Struct(name='dual_surface_description',
                              dim=self.dim,
                              n_dual_fa=conn.shape[0],
                              n_dual_fp=self.dim,
                              n_fa=n_fa,
                              n_edge=n_edge,
                              n_nod=n_nod,
                              n_components=n_components,
                              n_dof=n_nod * n_components,
                              dual_coors=dual_coors,
                              coor_offset=coor_offset,
                              e_sort=e_sort,
                              conn=conn,
                              tri_conn=tri_conn,
                              map_er_e=map_er_e,
                              map_er_ed=map_er_ed,
                              face_map=face_map,
                              asm_conn=asm_conn,
                              nodal_normals=nodal_normals,
                              edge_centre_coors=edge_centre_coors,
                              edge_normals=edge_normals,
                              edge_dirs=edge_dirs,
                              edge_ortho=edge_ortho)

        return dual_surface
Ejemplo n.º 7
0
    def describe_dual_surface(self, surface):
        n_fa, n_edge = surface.n_fa, self.sgel.n_edge

        mesh_coors = self.mesh_coors

        # Face centres.
        fcoors = mesh_coors[surface.econn]
        centre_coors = nm.dot(self.bf.squeeze(), fcoors)

        surface_coors = mesh_coors[surface.nodes]

        dual_coors = nm.r_[surface_coors, centre_coors]
        coor_offset = surface.nodes.shape[0]

        # Normals in primary mesh nodes.
        nodal_normals = compute_nodal_normals(surface.nodes, self.region,
                                              self.field)

        ee = surface.leconn[:,self.sgel.edges].copy()
        edges_per_face = ee.copy()
        sh = edges_per_face.shape
        ee.shape = edges_per_face.shape = (sh[0] * sh[1], sh[2])
        edges_per_face.sort(axis=1)

        eo = nm.empty((sh[0] * sh[1],), dtype=nm.object)
        eo[:] = [tuple(ii) for ii in edges_per_face]

        ueo, e_sort, e_id = unique(eo, return_index=True, return_inverse=True)
        ueo = edges_per_face[e_sort]

        # edge centre, edge point 1, face centre, edge point 2
        conn = nm.empty((n_edge * n_fa, 4), dtype=nm.int32)
        conn[:,0] = e_id
        conn[:,1] = ee[:,0]
        conn[:,2] = nm.repeat(nm.arange(n_fa, dtype=nm.int32), n_edge) \
                    + coor_offset
        conn[:,3] = ee[:,1]

        # face centre, edge point 2, edge point 1
        tri_conn = nm.ascontiguousarray(conn[:,[2,1,3]])

        # Ensure orientation - outward normal.
        cc = dual_coors[tri_conn]
        v1 = cc[:,1] - cc[:,0]
        v2 = cc[:,2] - cc[:,0]

        normals = nm.cross(v1, v2)
        nn = nodal_normals[surface.leconn].sum(axis=1).repeat(n_edge, 0)
        centre_normals = (1.0 / surface.n_fp) * nn
        centre_normals /= la.norm_l2_along_axis(centre_normals)[:,None]
        dot = nm.sum(normals * centre_normals, axis=1)

        assert_((dot > 0.0).all())

        # Prepare mapping from reference triangle e_R to a
        # triangle within reference face e_D.
        gel = self.gel.surface_facet
        ref_coors = gel.coors
        ref_centre = nm.dot(self.bf.squeeze(), ref_coors)
        cc = nm.r_[ref_coors, ref_centre[None,:]]
        rconn = nm.empty((n_edge, 3), dtype=nm.int32)
        rconn[:,0] = gel.n_vertex
        rconn[:,1] = gel.edges[:,0]
        rconn[:,2] = gel.edges[:,1]

        map_er_ed = VolumeMapping(cc, rconn, gel=gel)

        # Prepare mapping from reference triangle e_R to a
        # physical triangle e.
        map_er_e = SurfaceMapping(dual_coors, tri_conn, gel=gel)

        # Compute triangle basis (edge) vectors.
        nn = surface.nodes[ueo]
        edge_coors = mesh_coors[nn]

        edge_centre_coors = 0.5 * edge_coors.sum(axis=1)

        edge_normals = 0.5 * nodal_normals[ueo].sum(axis=1)

        edge_normals /= la.norm_l2_along_axis(edge_normals)[:,None]

        nn = surface.nodes[ueo]
        edge_dirs = edge_coors[:,1] - edge_coors[:,0]
        edge_dirs /= la.norm_l2_along_axis(edge_dirs)[:,None]

        edge_ortho = nm.cross(edge_normals, edge_dirs)
        edge_ortho /= la.norm_l2_along_axis(edge_ortho)[:,None]

        # Primary face - dual sub-faces map.
        # i-th row: indices to conn corresponding to sub-faces of i-th face.
        face_map = nm.arange(n_fa * n_edge, dtype=nm.int32)
        face_map.shape = (n_fa, n_edge)

        # The actual connectivity for assembling (unique nodes per master
        # faces).
        asm_conn = e_id[face_map]

        n_nod = ueo.shape[0] # One node per unique edge.
        n_components = self.dim - 1

        dual_surface = Struct(name = 'dual_surface_description',
                              dim = self.dim,
                              n_dual_fa = conn.shape[0],
                              n_dual_fp = self.dim,
                              n_fa = n_fa,
                              n_edge = n_edge,
                              n_nod = n_nod,
                              n_components = n_components,
                              n_dof = n_nod * n_components,
                              dual_coors = dual_coors,
                              coor_offset = coor_offset,
                              e_sort = e_sort,
                              conn = conn,
                              tri_conn = tri_conn,
                              map_er_e = map_er_e,
                              map_er_ed = map_er_ed,
                              face_map = face_map,
                              asm_conn = asm_conn,
                              nodal_normals = nodal_normals,
                              edge_centre_coors = edge_centre_coors,
                              edge_normals = edge_normals,
                              edge_dirs = edge_dirs,
                              edge_ortho = edge_ortho)

        return dual_surface