Example #1
0
    def __init__(self,
                 mesh,
                 elem,
                 mapping,
                 intorder: Optional[int] = None,
                 side: int = 0):
        super(MortarBasis, self).__init__(mesh, elem, mapping, intorder)

        self.ib1 = InteriorBasis(mesh.mesh1, elem)
        self.ib2 = InteriorBasis(mesh.mesh2, elem)

        self.X, self.W = get_quadrature(self.brefdom, self.intorder)

        self.find = np.nonzero(self.mesh.f2t[1, :] != -1)[0]
        self.tind = self.mesh.f2t[side, self.find]

        # boundary refdom to global facet
        x = self.mapping.G(self.X, find=self.find)
        # global facet to refdom facet
        Y = self.mapping.invF(x, tind=self.tind)

        self.normals = np.repeat(mesh.normals[:, :, None], len(self.W), axis=2)

        self.nelems = len(self.find)

        self.basis = [self.elem.gbasis(self.mapping, Y, j, self.tind) for j in range(self.Nbfun)]

        self.dx = np.abs(self.mapping.detDG(self.X, find=self.find)) * np.tile(self.W, (self.nelems, 1))

        if side == 0:
            self.element_dofs = self.ib1.element_dofs[:, self.tind]
        elif side == 1:
            self.element_dofs = self.ib2.element_dofs[:, self.tind - mesh.mesh1.t.shape[1]] + self.ib1.N

        self.N = self.ib1.N + self.ib2.N
Example #2
0
    def __init__(self,
                 mesh,
                 elem,
                 mapping=None,
                 intorder=None,
                 side=None,
                 dofnum=None):
        super(FacetBasis, self).__init__(mesh, elem, mapping, intorder)
        if dofnum is not None:
            self.dofnum = dofnum
            self.Nbfun = self.dofnum.t_dof.shape[0]

        self.X, self.W = get_quadrature(self.brefdom, self.intorder)

        # triangles where the basis is evaluated
        if side is None:
            self.find = np.nonzero(self.mesh.f2t[1, :] == -1)[0]
            self.tind = self.mesh.f2t[0, self.find]
        elif side == 0 or side == 1:
            self.find = np.nonzero(self.mesh.f2t[1, :] != -1)[0]
            self.tind = self.mesh.f2t[side, self.find]
        else:
            raise Exception(
                "Parameter side must be 0 or 1. Facet shares only two elements."
            )

        # boundary refdom to global facet
        x = self.mapping.G(self.X, find=self.find)
        # global facet to refdom facet
        Y = self.mapping.invF(x, tind=self.tind)

        if hasattr(mesh, 'normals'):
            self.normals = np.repeat(mesh.normals[:, :, None],
                                     len(self.W),
                                     axis=2)
        else:
            # construct normal vectors from side=0 always
            Y0 = self.mapping.invF(x, tind=self.mesh.f2t[
                0,
                self.find])  # TODO check why without this works also (Y0 = Y)
            self.normals = self.mapping.normals(Y0, self.mesh.f2t[0,
                                                                  self.find],
                                                self.find, self.mesh.t2f)

        self.nf = len(self.find)

        self.basis = list(
            zip(*[
                self.elem.gbasis(self.mapping, Y, j, self.tind)
                for j in range(self.Nbfun)
            ]))

        self.nelems = self.nf
        self.dx = np.abs(self.mapping.detDG(self.X, find=self.find)) * np.tile(
            self.W, (self.nelems, 1))

        self.dofnum.t_dof = self.dofnum.t_dof[:, self.
                                              tind]  # TODO this is required for asm(). Check for other options.
Example #3
0
    def __init__(self,
                 mesh: Mesh,
                 elem: Element,
                 mapping: Mapping = None,
                 intorder: int = None,
                 elements: ndarray = None,
                 quadrature: Tuple[ndarray, ndarray] = None):
        """Combine :class:`~skfem.mesh.Mesh` and :class:`~skfem.element.Element`
        into a set of precomputed global basis functions.

        Parameters
        ----------
        mesh
            An object of type :class:`~skfem.mesh.Mesh`.
        elem
            An object of type :class:`~skfem.element.Element`.
        mapping
            An object of type :class:`skfem.mapping.Mapping`. If `None`, uses
            `mesh.mapping`.
        intorder
            Optional integration order, i.e. the degree of polynomials that are
            integrated exactly by the used quadrature. Not used if `quadrature`
            is specified.
        elements
            Optional subset of element indices.
        quadrature
            Optional tuple of quadrature points and weights.

        """
        super(InteriorBasis, self).__init__(mesh, elem, mapping)

        if quadrature is not None:
            self.X, self.W = quadrature
        else:
            self.X, self.W = get_quadrature(
                self.refdom,
                intorder if intorder is not None else 2 * self.elem.maxdeg)

        self.basis = [
            self.elem.gbasis(self.mapping, self.X, j, tind=elements)
            for j in range(self.Nbfun)
        ]

        if elements is None:
            self.nelems = self.mesh.t.shape[1]
            self.tind = np.arange(self.nelems, dtype=np.int64)
        else:
            self.nelems = len(elements)
            self.tind = elements

        self.dx = (np.abs(self.mapping.detDF(self.X, tind=elements)) *
                   np.tile(self.W, (self.nelems, 1)))

        self.element_dofs = self.element_dofs[:, self.tind]
Example #4
0
    def __init__(self, mesh, elem, mapping=None, intorder=None):
        super(InteriorBasis, self).__init__(mesh, elem, mapping, intorder)

        self.X, self.W = get_quadrature(self.refdom, self.intorder)

        self.basis = list(
            zip(*[
                self.elem.gbasis(self.mapping, self.X, j)
                for j in range(self.Nbfun)
            ]))

        self.nelems = self.nt
        self.dx = np.abs(self.mapping.detDF(self.X)) * np.tile(
            self.W, (self.nelems, 1))
Example #5
0
    def __init__(self,
                 mesh: Mesh,
                 elem: Element,
                 mapping: Optional[Mapping] = None,
                 intorder: Optional[int] = None):
        super(InteriorBasis, self).__init__(mesh, elem, mapping, intorder)

        self.X, self.W = get_quadrature(self.refdom, self.intorder)

        self.basis = [
            self.elem.gbasis(self.mapping, self.X, j)
            for j in range(self.Nbfun)
        ]

        self.nelems = self.mesh.t.shape[1]
        self.dx = np.abs(self.mapping.detDF(self.X)) * np.tile(
            self.W, (self.nelems, 1))
Example #6
0
    def __init__(self,
                 mesh: Mesh,
                 elem: Element,
                 mapping: Optional[Mapping] = None,
                 intorder: Optional[int] = None,
                 elements: Optional[ndarray] = None):
        """Combine :class:`~skfem.mesh.Mesh` and :class:`~skfem.element.Element` into a
        set of precomputed global basis functions.

        Parameters
        ----------
        mesh
            An object of type :class:`~skfem.mesh.Mesh`.
        elem
            An object of type :class:`~skfem.element.Element`.
        mapping
            An object of type :class:`~skfem.mapping.Mapping`.
        intorder
            Optional integration order, i.e. the degree of polynomials that are
            integrated exactly by the used quadrature.
        elements
            Optional subset of element indices.

        """
        super(InteriorBasis, self).__init__(mesh, elem, mapping, intorder)

        self.X, self.W = get_quadrature(self.refdom, self.intorder)

        self.basis = [
            self.elem.gbasis(self.mapping, self.X, j, tind=elements)
            for j in range(self.Nbfun)
        ]

        if elements is None:
            self.nelems = self.mesh.t.shape[1]
            self.tind = np.arange(self.nelems, dtype=np.int64)
        else:
            self.nelems = len(elements)
            self.tind = elements

        self.dx = (np.abs(self.mapping.detDF(self.X, tind=elements)) *
                   np.tile(self.W, (self.nelems, 1)))

        self.element_dofs = self.element_dofs[:, self.tind]
Example #7
0
    def __init__(self,
                 mesh: Mesh,
                 elem: Element,
                 mapping: Optional[Mapping] = None,
                 intorder: Optional[int] = None,
                 quadrature: Optional[Tuple[ndarray, ndarray]] = None,
                 refdom: Type[Refdom] = Refdom,
                 dofs: Optional[Dofs] = None):

        if mesh.refdom != elem.refdom:
            raise ValueError("Incompatible Mesh and Element.")

        self.mapping = mesh._mapping() if mapping is None else mapping
        self.dofs = Dofs(mesh, elem) if dofs is None else dofs

        # global degree-of-freedom location
        try:
            doflocs = self.mapping.F(elem.doflocs.T)
            self.doflocs = np.zeros((doflocs.shape[0], self.N))

            # match mapped dofs and global dof numbering
            for itr in range(doflocs.shape[0]):
                for jtr in range(self.dofs.element_dofs.shape[0]):
                    self.doflocs[itr, self.dofs.element_dofs[jtr]] =\
                        doflocs[itr, :, jtr]
        except Exception:
            logger.warning("Unable to calculate global DOF locations.")

        self.mesh = mesh
        self.elem = elem

        self.Nbfun = self.dofs.element_dofs.shape[0]

        self.nelems = 0  # subclasses should overwrite

        if quadrature is not None:
            self.X, self.W = quadrature
        else:
            self.X, self.W = get_quadrature(
                refdom,
                intorder if intorder is not None else 2 * self.elem.maxdeg
            )
Example #8
0
    def __init__(self,
                 mesh,
                 elem,
                 mapping=None,
                 intorder: int = None,
                 side: int = None,
                 facets: ndarray = None,
                 quadrature: Tuple[ndarray, ndarray] = None):
        """Combine :class:`~skfem.mesh.Mesh` and :class:`~skfem.element.Element`
        into a set of precomputed global basis functions at element facets.

        Parameters
        ----------
        mesh
            An object of type :class:`~skfem.mesh.Mesh`.
        elem
            An object of type :class:`~skfem.element.Element`.
        mapping
            An object of type :class:`skfem.mapping.Mapping`. If `None`, uses
            `mesh.mapping`.
        intorder
            Optional integration order, i.e. the degree of polynomials that are
            integrated exactly by the used quadrature. Not used if `quadrature`
            is specified.
        side
            If 0 or 1, basis functions are evaluated on the interior facets.
            The numbers 0 and 1 refer to the different sides of the facets.
            Side 0 corresponds to the indices `mesh.f2t[0]`. If `None`, basis
            is evaluated only on the exterior facets.
        facets
            Optional subset of facet indices.
        quadrature
            Optional tuple of quadrature points and weights.

        """
        super(FacetBasis, self).__init__(mesh, elem, mapping)

        if quadrature is not None:
            self.X, self.W = quadrature
        else:
            self.X, self.W = get_quadrature(
                self.brefdom,
                intorder if intorder is not None else 2 * self.elem.maxdeg)

        # facets where the basis is evaluated
        if facets is None:
            if side is None:
                self.find = np.nonzero(self.mesh.f2t[1] == -1)[0]
                self.tind = self.mesh.f2t[0, self.find]
            elif hasattr(self.mapping, 'helper_to_orig') and side in [0, 1]:
                self.mapping.side = side
                self.find = self.mapping.helper_to_orig[side]
                self.tind = self.mesh.f2t[0, self.find]
            elif side in [0, 1]:
                self.find = np.nonzero(self.mesh.f2t[1] != -1)[0]
                self.tind = self.mesh.f2t[side, self.find]
            else:
                raise Exception("Parameter 'side' must be either 0 or 1. "
                                "A facet shares only two elements.")
        else:
            self.find = facets
            self.tind = self.mesh.f2t[0, self.find]

        # boundary refdom to global facet
        x = self.mapping.G(self.X, find=self.find)
        # global facet to refdom facet
        Y = self.mapping.invF(x, tind=self.tind)

        # construct normal vectors from side=0 always
        Y0 = self.mapping.invF(x, tind=self.mesh.f2t[0, self.find])
        self.normals = DiscreteField(value=self.mapping.normals(
            Y0, self.mesh.f2t[0, self.find], self.find, self.mesh.t2f))

        self.nelems = len(self.find)

        self.basis = [
            self.elem.gbasis(self.mapping, Y, j, tind=self.tind)
            for j in range(self.Nbfun)
        ]

        self.dx = (np.abs(self.mapping.detDG(self.X, find=self.find)) *
                   np.tile(self.W, (self.nelems, 1)))
Example #9
0
    def __init__(self,
                 mesh,
                 elem,
                 mapping=None,
                 intorder: Optional[int] = None,
                 side: Optional[int] = None,
                 facets: Optional[ndarray] = None):
        """Combine :class:`~skfem.mesh.Mesh` and :class:`~skfem.element.Element`
        into a set of precomputed global basis functions at element facets.

        Parameters
        ----------
        mesh
            An object of type :class:`~skfem.mesh.Mesh`.
        elem
            An object of type :class:`~skfem.element.Element`.
        mapping
            An object of type :class:`~skfem.mapping.Mapping`.
        intorder
            Optional integration order, i.e. the degree of polynomials that are
            integrated exactly by the used quadrature.
        side
            If 0 or 1, the basis functions are evaluated on the interior facets.
            The numbers 0 and 1 refer to the different sides of the facets.
            Side 0 corresponds to the indices mesh.f2t[0, :].
        facets
            Optional subset of facet indices.

        """
        super(FacetBasis, self).__init__(mesh, elem, mapping, intorder)

        self.X, self.W = get_quadrature(self.brefdom, self.intorder)

        # facets where the basis is evaluated
        if facets is None:
            if side is None:
                self.find = np.nonzero(self.mesh.f2t[1, :] == -1)[0]
                self.tind = self.mesh.f2t[0, self.find]
            elif side == 0 or side == 1:
                self.find = np.nonzero(self.mesh.f2t[1, :] != -1)[0]
                self.tind = self.mesh.f2t[side, self.find]
            else:
                raise Exception("Parameter 'side' must be either 0 or 1. "
                                "A facet shares only two elements.")
        else:
            self.find = facets
            self.tind = self.mesh.f2t[0, self.find]

        # boundary refdom to global facet
        x = self.mapping.G(self.X, find=self.find)
        # global facet to refdom facet
        Y = self.mapping.invF(x, tind=self.tind)

        if hasattr(mesh, 'normals'):
            self.normals = np.repeat(mesh.normals[:, :, None],
                                     len(self.W),
                                     axis=2)
        else:
            # construct normal vectors from side=0 always
            Y0 = self.mapping.invF(x, tind=self.mesh.f2t[0, self.find])
            self.normals = self.mapping.normals(Y0, self.mesh.f2t[0,
                                                                  self.find],
                                                self.find, self.mesh.t2f)

        self.nelems = len(self.find)

        self.basis = [
            self.elem.gbasis(self.mapping, Y, j, self.tind)
            for j in range(self.Nbfun)
        ]

        self.dx = np.abs(self.mapping.detDG(self.X, find=self.find)) *\
            np.tile(self.W, (self.nelems, 1))

        self.element_dofs = self.element_dofs[:, self.tind]