Ejemplo n.º 1
0
Archivo: aw.py Proyecto: jmv2009/FInAT
    def basis_transformation(self, coordinate_mapping):
        """The extra 6 dofs removed here correspond to the constraints."""
        V = numpy.zeros((30, 24), dtype=object)

        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        J = coordinate_mapping.jacobian_at([1 / 3, 1 / 3])

        W = numpy.zeros((3, 3), dtype=object)
        W[0, 0] = J[1, 1] * J[1, 1]
        W[0, 1] = -2 * J[1, 1] * J[0, 1]
        W[0, 2] = J[0, 1] * J[0, 1]
        W[1, 0] = -1 * J[1, 1] * J[1, 0]
        W[1, 1] = J[1, 1] * J[0, 0] + J[0, 1] * J[1, 0]
        W[1, 2] = -1 * J[0, 1] * J[0, 0]
        W[2, 0] = J[1, 0] * J[1, 0]
        W[2, 1] = -2 * J[1, 0] * J[0, 0]
        W[2, 2] = J[0, 0] * J[0, 0]

        # Put into the right rows and columns.
        V[0:3, 0:3] = V[3:6, 3:6] = V[6:9, 6:9] = W

        V[9:21, 9:21] = _edge_transform(self.cell, coordinate_mapping)

        for i in range(21, 24):
            V[i, i] = Literal(1)

        return ListTensor(V.T)
Ejemplo n.º 2
0
    def basis_transformation(self, coordinate_mapping):
        V = numpy.zeros((20, 9), dtype=object)

        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        for i in range(0, 9, 3):
            V[i, i] = Literal(1)
            V[i+2, i+2] = Literal(1)

        T = self.cell

        # This bypasses the GEM wrapper.
        that = numpy.array([T.compute_normalized_edge_tangent(i) for i in range(3)])
        nhat = numpy.array([T.compute_normal(i) for i in range(3)])

        detJ = coordinate_mapping.detJ_at([1/3, 1/3])
        J = coordinate_mapping.jacobian_at([1/3, 1/3])
        J_np = numpy.array([[J[0, 0], J[0, 1]],
                            [J[1, 0], J[1, 1]]])
        JTJ = J_np.T @ J_np

        for e in range(3):
            # Compute alpha and beta for the edge.
            Ghat_T = numpy.array([nhat[e, :], that[e, :]])

            (alpha, beta) = Ghat_T @ JTJ @ that[e, :] / detJ

            # Stuff into the right rows and columns.
            idx = 3*e + 1
            V[idx, idx-1] = Literal(-1) * alpha / beta
            V[idx, idx] = Literal(1) / beta

        return ListTensor(V.T)
Ejemplo n.º 3
0
Archivo: aw.py Proyecto: FInAT/FInAT
    def basis_transformation(self, coordinate_mapping):
        """The extra 6 dofs removed here correspond to the constraints."""
        V = numpy.zeros((30, 24), dtype=object)

        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        W = _evaluation_transform(coordinate_mapping)

        # Put into the right rows and columns.
        V[0:3, 0:3] = V[3:6, 3:6] = V[6:9, 6:9] = W

        V[9:21, 9:21] = _edge_transform(self.cell, coordinate_mapping)

        # internal DOFs
        detJ = coordinate_mapping.detJ_at([1/3, 1/3])
        V[21:24, 21:24] = W / detJ

        # RESCALING FOR CONDITIONING
        h = coordinate_mapping.cell_size()

        for e in range(3):
            eff_h = h[e]
            for i in range(24):
                V[i, 3*e] = V[i, 3*e]/(eff_h*eff_h)
                V[i, 1+3*e] = V[i, 1+3*e]/(eff_h*eff_h)
                V[i, 2+3*e] = V[i, 2+3*e]/(eff_h*eff_h)

        # Note: that the edge DOFs are scaled by edge lengths in FIAT implies
        # that they are already have the necessary rescaling to improve
        # conditioning.

        return ListTensor(V.T)
Ejemplo n.º 4
0
    def basis_transformation(self, coordinate_mapping):
        Js = [
            coordinate_mapping.jacobian_at(vertex)
            for vertex in self.cell.get_vertices()
        ]

        h = coordinate_mapping.cell_size()

        d = self.cell.get_dimension()
        numbf = self.space_dimension()

        M = numpy.eye(numbf, dtype=object)

        for multiindex in numpy.ndindex(M.shape):
            M[multiindex] = Literal(M[multiindex])

        cur = 0
        for i in range(d + 1):
            cur += 1  # skip the vertex
            J = Js[i]
            for j in range(d):
                for k in range(d):
                    M[cur + j, cur + k] = J[j, k] / h[i]
            cur += d

        return ListTensor(M)
Ejemplo n.º 5
0
Archivo: aw.py Proyecto: jmv2009/FInAT
    def basis_transformation(self, coordinate_mapping):
        """Note, the extra 3 dofs which are removed here
        correspond to the constraints."""

        T = self.cell
        V = numpy.zeros((18, 15), dtype=object)
        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        V[:12, :12] = _edge_transform(T, coordinate_mapping)

        # internal dofs
        for i in range(12, 15):
            V[i, i] = Literal(1)

        return ListTensor(V.T)
Ejemplo n.º 6
0
    def basis_transformation(self, coordinate_mapping):
        # Jacobians at edge midpoints
        J = coordinate_mapping.jacobian_at([1/3, 1/3])

        rns = coordinate_mapping.reference_normals()
        pns = coordinate_mapping.physical_normals()

        pts = coordinate_mapping.physical_tangents()

        pel = coordinate_mapping.physical_edge_lengths()

        V = numpy.eye(6, dtype=object)
        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        for i in range(3):
            V[i+3, i+3] = (rns[i, 0]*(pns[i, 0]*J[0, 0] + pns[i, 1]*J[1, 0])
                           + rns[i, 1]*(pns[i, 0]*J[0, 1] + pns[i, 1]*J[1, 1]))

        for i, c in enumerate([(1, 2), (0, 2), (0, 1)]):
            B12 = (rns[i, 0]*(pts[i, 0]*J[0, 0] + pts[i, 1]*J[1, 0])
                   + rns[i, 1]*(pts[i, 0]*J[0, 1] + pts[i, 1]*J[1, 1]))
            V[3+i, c[0]] = -1*B12 / pel[i]
            V[3+i, c[1]] = B12 / pel[i]

        # diagonal post-scaling to patch up conditioning
        h = coordinate_mapping.cell_size()

        for e in range(3):
            v0id, v1id = [i for i in range(3) if i != e]
            for i in range(6):
                V[i, 3+e] = 2*V[i, 3+e] / (h[v0id] + h[v1id])

        return ListTensor(V.T)
Ejemplo n.º 7
0
def _slate2gem_inverse(expr, self):
    tensor, = expr.children
    if expr.diagonal:
        # optimise inverse on diagonal tensor by translating to
        # matrix which contains the reciprocal values of the diagonal tensor
        A, = map(self, expr.children)
        i, j = (Index(extent=s) for s in A.shape)
        return ComponentTensor(
            Product(Division(Literal(1), Indexed(A, (i, i))), Delta(i, j)),
            (i, j))
    else:
        return Inverse(self(tensor))
Ejemplo n.º 8
0
Archivo: aw.py Proyecto: FInAT/FInAT
def _edge_transform(T, coordinate_mapping):
    Vsub = numpy.zeros((12, 12), dtype=object)

    for multiindex in numpy.ndindex(Vsub.shape):
        Vsub[multiindex] = Literal(Vsub[multiindex])

    for i in range(0, 12, 2):
        Vsub[i, i] = Literal(1)

    # This bypasses the GEM wrapper.
    that = numpy.array([T.compute_normalized_edge_tangent(i) for i in range(3)])
    nhat = numpy.array([T.compute_normal(i) for i in range(3)])

    detJ = coordinate_mapping.detJ_at([1/3, 1/3])
    J = coordinate_mapping.jacobian_at([1/3, 1/3])
    J_np = numpy.array([[J[0, 0], J[0, 1]],
                        [J[1, 0], J[1, 1]]])
    JTJ = J_np.T @ J_np

    for e in range(3):
        # Compute alpha and beta for the edge.
        Ghat_T = numpy.array([nhat[e, :], that[e, :]])

        (alpha, beta) = Ghat_T @ JTJ @ that[e, :] / detJ
        # Stuff into the right rows and columns.
        (idx1, idx2) = (4*e + 1, 4*e + 3)
        Vsub[idx1, idx1-1] = Literal(-1) * alpha / beta
        Vsub[idx1, idx1] = Literal(1) / beta
        Vsub[idx2, idx2-1] = Literal(-1) * alpha / beta
        Vsub[idx2, idx2] = Literal(1) / beta

    return Vsub
Ejemplo n.º 9
0
Archivo: aw.py Proyecto: FInAT/FInAT
    def basis_transformation(self, coordinate_mapping):
        """Note, the extra 3 dofs which are removed here
        correspond to the constraints."""

        T = self.cell
        V = numpy.zeros((18, 15), dtype=object)
        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        V[:12, :12] = _edge_transform(T, coordinate_mapping)

        # internal dofs
        W = _evaluation_transform(coordinate_mapping)
        detJ = coordinate_mapping.detJ_at([1/3, 1/3])

        V[12:15, 12:15] = W / detJ

        # Note: that the edge DOFs are scaled by edge lengths in FIAT implies
        # that they are already have the necessary rescaling to improve
        # conditioning.

        return ListTensor(V.T)
Ejemplo n.º 10
0
 def scalar_value(self, o):
     return Literal(o.value())
Ejemplo n.º 11
0
def _slate2gem_negative(expr, self):
    child, = map(self, expr.children)
    indices = tuple(make_indices(len(child.shape)))
    return ComponentTensor(Product(Literal(-1), Indexed(child, indices)),
                           indices)
Ejemplo n.º 12
0
def _slate2gem_reciprocal(expr, self):
    child, = map(self, expr.children)
    indices = tuple(make_indices(len(child.shape)))
    return ComponentTensor(Division(Literal(1.), Indexed(child, indices)),
                           indices)
Ejemplo n.º 13
0
    def basis_transformation(self, coordinate_mapping):
        # Jacobians at edge midpoints
        J = coordinate_mapping.jacobian_at([1 / 3, 1 / 3])

        rns = coordinate_mapping.reference_normals()
        pns = coordinate_mapping.physical_normals()

        pts = coordinate_mapping.physical_tangents()

        pel = coordinate_mapping.physical_edge_lengths()

        V = numpy.zeros((21, 21), dtype=object)

        for multiindex in numpy.ndindex(V.shape):
            V[multiindex] = Literal(V[multiindex])

        for v in range(3):
            s = 6 * v
            V[s, s] = Literal(1)
            for i in range(2):
                for j in range(2):
                    V[s + 1 + i, s + 1 + j] = J[j, i]
            V[s + 3, s + 3] = J[0, 0] * J[0, 0]
            V[s + 3, s + 4] = 2 * J[0, 0] * J[1, 0]
            V[s + 3, s + 5] = J[1, 0] * J[1, 0]
            V[s + 4, s + 3] = J[0, 0] * J[0, 1]
            V[s + 4, s + 4] = J[0, 0] * J[1, 1] + J[1, 0] * J[0, 1]
            V[s + 4, s + 5] = J[1, 0] * J[1, 1]
            V[s + 5, s + 3] = J[0, 1] * J[0, 1]
            V[s + 5, s + 4] = 2 * J[0, 1] * J[1, 1]
            V[s + 5, s + 5] = J[1, 1] * J[1, 1]

        for e in range(3):
            v0id, v1id = [i for i in range(3) if i != e]

            # nhat . J^{-T} . t
            foo = (rns[e, 0] * (J[0, 0] * pts[e, 0] + J[1, 0] * pts[e, 1]) +
                   rns[e, 1] * (J[0, 1] * pts[e, 0] + J[1, 1] * pts[e, 1]))

            # vertex points
            V[18 + e, 6 * v0id] = -15 / 8 * (foo / pel[e])
            V[18 + e, 6 * v1id] = 15 / 8 * (foo / pel[e])

            # vertex derivatives
            for i in (0, 1):
                V[18 + e, 6 * v0id + 1 + i] = -7 / 16 * foo * pts[e, i]
                V[18 + e, 6 * v1id + 1 + i] = V[18 + e, 6 * v0id + 1 + i]

            # second derivatives
            tau = [
                pts[e, 0] * pts[e, 0], 2 * pts[e, 0] * pts[e, 1],
                pts[e, 1] * pts[e, 1]
            ]

            for i in (0, 1, 2):
                V[18 + e, 6 * v0id + 3 + i] = -1 / 32 * (pel[e] * foo * tau[i])
                V[18 + e, 6 * v1id + 3 + i] = 1 / 32 * (pel[e] * foo * tau[i])

            V[18 + e, 18 +
              e] = (rns[e, 0] * (J[0, 0] * pns[e, 0] + J[1, 0] * pns[e, 1]) +
                    rns[e, 1] * (J[0, 1] * pns[e, 0] + J[1, 1] * pns[e, 1]))

        # Patch up conditioning
        h = coordinate_mapping.cell_size()

        for v in range(3):
            for k in range(2):
                for i in range(21):
                    V[i, 6 * v + 1 + k] = V[i, 6 * v + 1 + k] / h[v]
            for k in range(3):
                for i in range(21):
                    V[i, 6 * v + 3 + k] = V[i, 6 * v + 3 + k] / (h[v] * h[v])
        for e in range(3):
            v0id, v1id = [i for i in range(3) if i != e]
            for i in range(21):
                V[i, 18 + e] = 2 * V[i, 18 + e] / (h[v0id] + h[v1id])

        return ListTensor(V.T)