Beispiel #1
0
    def __init__(self, ref_el, degree, shape=tuple()):

        if shape == tuple():
            num_components = 1
        else:
            flat_shape = numpy.ravel(shape)
            num_components = numpy.prod(flat_shape)
        num_exp_functions = expansions.polynomial_dimension(ref_el, degree)
        num_members = num_components * num_exp_functions
        embedded_degree = degree
        expansion_set = expansions.get_expansion_set(ref_el)
        sd = ref_el.get_spatial_dimension()

        # set up coefficients
        coeffs_shape = tuple([num_members] + list(shape) + [num_exp_functions])
        coeffs = numpy.zeros(coeffs_shape, "d")

        # use functional's index_iterator function
        cur_bf = 0

        if shape == tuple():
            coeffs = numpy.eye(num_members)
        else:
            for idx in index_iterator(shape):
                n = expansions.polynomial_dimension(ref_el, embedded_degree)
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + list(idx) + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1

        # construct dmats
        if degree == 0:
            dmats = [numpy.array([[0.0]], "d") for i in range(sd)]
        else:
            pts = ref_el.make_points(sd, 0, degree + sd + 1)

            v = numpy.transpose(expansion_set.tabulate(degree, pts))
            vinv = numpy.linalg.inv(v)

            dv = expansion_set.tabulate_derivatives(degree, pts)
            dtildes = [[[a[1][i] for a in dvrow] for dvrow in dv]
                       for i in range(sd)]

            dmats = [
                numpy.dot(vinv, numpy.transpose(dtilde)) for dtilde in dtildes
            ]

        PolynomialSet.__init__(self, ref_el, degree, embedded_degree,
                               expansion_set, coeffs, dmats)
Beispiel #2
0
    def __init__(self, ref_el, degree, shape=tuple()):

        if shape == tuple():
            num_components = 1
        else:
            flat_shape = numpy.ravel(shape)
            num_components = numpy.prod(flat_shape)
        num_exp_functions = expansions.polynomial_dimension(ref_el, degree)
        num_members = num_components * num_exp_functions
        embedded_degree = degree
        expansion_set = expansions.get_expansion_set(ref_el)
        sd = ref_el.get_spatial_dimension()

        # set up coefficients
        coeffs_shape = tuple([num_members] + list(shape) + [num_exp_functions])
        coeffs = numpy.zeros(coeffs_shape, "d")

        # use functional's index_iterator function
        cur_bf = 0

        if shape == tuple():
            coeffs = numpy.eye(num_members)
        else:
            for idx in index_iterator(shape):
                n = expansions.polynomial_dimension(ref_el, embedded_degree)
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + list(idx) + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1

        # construct dmats
        if degree == 0:
            dmats = [numpy.array([[0.0]], "d") for i in range(sd)]
        else:
            pts = ref_el.make_points(sd, 0, degree + sd + 1)

            v = numpy.transpose(expansion_set.tabulate(degree, pts))
            vinv = numpy.linalg.inv(v)

            dv = expansion_set.tabulate_derivatives(degree, pts)
            dtildes = [[[a[1][i] for a in dvrow] for dvrow in dv]
                       for i in range(sd)]

            dmats = [numpy.dot(vinv, numpy.transpose(dtilde))
                     for dtilde in dtildes]

        PolynomialSet.__init__(self, ref_el, degree, embedded_degree,
                               expansion_set, coeffs, dmats)
Beispiel #3
0
    def __init__(self, ref_el, degree):
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        # codimension 1 facets
        for i in range(len(t[sd - 1])):
            pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointScaledNormalEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal nodes.  Let's just use points at a lattice
        if degree > 0:
            cpe = functional.ComponentPointEvaluation
            pts = ref_el.make_points(sd, 0, degree + sd)
            for d in range(sd):
                for i in range(len(pts)):
                    l_cur = cpe(ref_el, d, (sd, ), pts[i])
                    nodes.append(l_cur)

            # Q = quadrature.make_quadrature(ref_el, 2 * ( degree + 1 ))
            # qpts = Q.get_points()
            # Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
            # zero_index = tuple([0 for i in range(sd)])
            # Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

            # for d in range(sd):
            #     for i in range(Pkm1_at_qpts.shape[0]):
            #         phi_cur = Pkm1_at_qpts[i, :]
            #         l_cur = functional.IntegralMoment(ref_el, Q, phi_cur, (d,), (sd,))
            #         nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)
        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}
        if degree > 0:
            num_internal_nodes = expansions.polynomial_dimension(
                ref_el, degree - 1)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes * sd))

        super(RTDualSet, self).__init__(nodes, ref_el, entity_ids)
Beispiel #4
0
    def __init__(self, ref_el, degree):
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        # codimension 1 facets
        for i in range(len(t[sd - 1])):
            pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
            for j in range(len(pts_cur)):
                pt_cur = pts_cur[j]
                f = functional.PointScaledNormalEvaluation(ref_el, i, pt_cur)
                nodes.append(f)

        # internal nodes.  Let's just use points at a lattice
        if degree > 0:
            cpe = functional.ComponentPointEvaluation
            pts = ref_el.make_points(sd, 0, degree + sd)
            for d in range(sd):
                for i in range(len(pts)):
                    l_cur = cpe(ref_el, d, (sd,), pts[i])
                    nodes.append(l_cur)

            # Q = quadrature.make_quadrature(ref_el, 2 * ( degree + 1 ))
            # qpts = Q.get_points()
            # Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
            # zero_index = tuple([0 for i in range(sd)])
            # Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

            # for d in range(sd):
            #     for i in range(Pkm1_at_qpts.shape[0]):
            #         phi_cur = Pkm1_at_qpts[i, :]
            #         l_cur = functional.IntegralMoment(ref_el, Q, phi_cur, (d,), (sd,))
            #         nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)
        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}
        if degree > 0:
            num_internal_nodes = expansions.polynomial_dimension(ref_el,
                                                                 degree - 1)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes * sd))

        super(RTDualSet, self).__init__(nodes, ref_el, entity_ids)
Beispiel #5
0
def RTSpace(ref_el, deg):
    """Constructs a basis for the the Raviart-Thomas space
    (P_k)^d + P_k x"""
    sd = ref_el.get_spatial_dimension()

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, deg + 1)
    dimPk = expansions.polynomial_dimension(ref_el, deg)
    dimPkm1 = expansions.polynomial_dimension(ref_el, deg - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * deg + 2)

    # have to work on this through "tabulate" interface
    # first, tabulate PkH at quadrature points
    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkHx_coeffs = numpy.zeros((PkH.get_num_members(),
                               sd,
                               Pkp1.get_num_members()), "d")

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            fooij = PkH_at_Qpts[i, :] * Qpts[:, j] * Qwts
            PkHx_coeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, fooij)

    PkHx = polynomial_set.PolynomialSet(ref_el,
                                        deg,
                                        deg + 1,
                                        vec_Pkp1.get_expansion_set(),
                                        PkHx_coeffs,
                                        vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1, PkHx)
Beispiel #6
0
def RTSpace(ref_el, deg):
    """Constructs a basis for the the Raviart-Thomas space
    (P_k)^d + P_k x"""
    sd = ref_el.get_spatial_dimension()

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, deg + 1)
    dimPk = expansions.polynomial_dimension(ref_el, deg)
    dimPkm1 = expansions.polynomial_dimension(ref_el, deg - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, deg + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * deg + 2)

    # have to work on this through "tabulate" interface
    # first, tabulate PkH at quadrature points
    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkHx_coeffs = numpy.zeros((PkH.get_num_members(),
                               sd,
                               Pkp1.get_num_members()), "d")

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            fooij = PkH_at_Qpts[i, :] * Qpts[:, j] * Qwts
            PkHx_coeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, fooij)

    PkHx = polynomial_set.PolynomialSet(ref_el,
                                        deg,
                                        deg + 1,
                                        vec_Pkp1.get_expansion_set(),
                                        PkHx_coeffs,
                                        vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1, PkHx)
Beispiel #7
0
    def __init__(self, ref_el, degree, size=None):

        sd = ref_el.get_spatial_dimension()
        if size is None:
            size = sd

        shape = (size, size)
        num_exp_functions = expansions.polynomial_dimension(ref_el, degree)
        num_components = size * (size + 1) // 2
        num_members = num_components * num_exp_functions
        embedded_degree = degree
        expansion_set = expansions.get_expansion_set(ref_el)

        # set up coefficients for symmetric tensors
        coeffs_shape = tuple([num_members] + list(shape) + [num_exp_functions])
        coeffs = numpy.zeros(coeffs_shape, "d")
        cur_bf = 0
        for [i, j] in index_iterator(shape):
            n = expansions.polynomial_dimension(ref_el, embedded_degree)
            if i == j:
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + [i, j] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1
            elif i < j:
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + [i, j] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_idx = tuple([cur_bf] + [j, i] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1

        # construct dmats. this is the same as ONPolynomialSet.
        pts = ref_el.make_points(sd, 0, degree + sd + 1)
        v = numpy.transpose(expansion_set.tabulate(degree, pts))
        vinv = numpy.linalg.inv(v)
        dv = expansion_set.tabulate_derivatives(degree, pts)
        dtildes = [[[a[1][i] for a in dvrow] for dvrow in dv]
                   for i in range(sd)]
        dmats = [
            numpy.dot(vinv, numpy.transpose(dtilde)) for dtilde in dtildes
        ]
        PolynomialSet.__init__(self, ref_el, degree, embedded_degree,
                               expansion_set, coeffs, dmats)
Beispiel #8
0
    def __init__(self, ref_el, degree, size=None):

        sd = ref_el.get_spatial_dimension()
        if size is None:
            size = sd

        shape = (size, size)
        num_exp_functions = expansions.polynomial_dimension(ref_el, degree)
        num_components = size * (size + 1) // 2
        num_members = num_components * num_exp_functions
        embedded_degree = degree
        expansion_set = expansions.get_expansion_set(ref_el)

        # set up coefficients for symmetric tensors
        coeffs_shape = tuple([num_members] + list(shape) + [num_exp_functions])
        coeffs = numpy.zeros(coeffs_shape, "d")
        cur_bf = 0
        for [i, j] in index_iterator(shape):
            n = expansions.polynomial_dimension(ref_el, embedded_degree)
            if i == j:
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + [i, j] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1
            elif i < j:
                for exp_bf in range(n):
                    cur_idx = tuple([cur_bf] + [i, j] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_idx = tuple([cur_bf] + [j, i] + [exp_bf])
                    coeffs[cur_idx] = 1.0
                    cur_bf += 1

        # construct dmats. this is the same as ONPolynomialSet.
        pts = ref_el.make_points(sd, 0, degree + sd + 1)
        v = numpy.transpose(expansion_set.tabulate(degree, pts))
        vinv = numpy.linalg.inv(v)
        dv = expansion_set.tabulate_derivatives(degree, pts)
        dtildes = [[[a[1][i] for a in dvrow] for dvrow in dv]
                   for i in range(sd)]
        dmats = [numpy.dot(vinv, numpy.transpose(dtilde)) for dtilde in dtildes]
        PolynomialSet.__init__(self, ref_el, degree, embedded_degree,
                               expansion_set, coeffs, dmats)
Beispiel #9
0
    def __init__(self, ref_el, degree, variant, quad_deg):
        entity_ids = {}
        nodes = []

        sd = ref_el.get_spatial_dimension()
        t = ref_el.get_topology()

        if variant == "integral":
            facet = ref_el.get_facet_element()
            # Facet nodes are \int_F v\cdot n p ds where p \in P_{q-1}
            # degree is q - 1
            Q = quadrature.make_quadrature(facet, quad_deg)
            Pq = polynomial_set.ONPolynomialSet(facet, degree)
            Pq_at_qpts = Pq.tabulate(Q.get_points())[tuple([0] * (sd - 1))]
            for f in range(len(t[sd - 1])):
                for i in range(Pq_at_qpts.shape[0]):
                    phi = Pq_at_qpts[i, :]
                    nodes.append(
                        functional.IntegralMomentOfScaledNormalEvaluation(
                            ref_el, Q, phi, f))

            # internal nodes. These are \int_T v \cdot p dx where p \in P_{q-2}^d
            if degree > 0:
                Q = quadrature.make_quadrature(ref_el, quad_deg)
                qpts = Q.get_points()
                Pkm1 = polynomial_set.ONPolynomialSet(ref_el, degree - 1)
                zero_index = tuple([0 for i in range(sd)])
                Pkm1_at_qpts = Pkm1.tabulate(qpts)[zero_index]

                for d in range(sd):
                    for i in range(Pkm1_at_qpts.shape[0]):
                        phi_cur = Pkm1_at_qpts[i, :]
                        l_cur = functional.IntegralMoment(
                            ref_el, Q, phi_cur, (d, ), (sd, ))
                        nodes.append(l_cur)

        elif variant == "point":
            # codimension 1 facets
            for i in range(len(t[sd - 1])):
                pts_cur = ref_el.make_points(sd - 1, i, sd + degree)
                for j in range(len(pts_cur)):
                    pt_cur = pts_cur[j]
                    f = functional.PointScaledNormalEvaluation(
                        ref_el, i, pt_cur)
                    nodes.append(f)

            # internal nodes.  Let's just use points at a lattice
            if degree > 0:
                cpe = functional.ComponentPointEvaluation
                pts = ref_el.make_points(sd, 0, degree + sd)
                for d in range(sd):
                    for i in range(len(pts)):
                        l_cur = cpe(ref_el, d, (sd, ), pts[i])
                        nodes.append(l_cur)

        # sets vertices (and in 3d, edges) to have no nodes
        for i in range(sd - 1):
            entity_ids[i] = {}
            for j in range(len(t[i])):
                entity_ids[i][j] = []

        cur = 0

        # set codimension 1 (edges 2d, faces 3d) dof
        pts_facet_0 = ref_el.make_points(sd - 1, 0, sd + degree)
        pts_per_facet = len(pts_facet_0)
        entity_ids[sd - 1] = {}
        for i in range(len(t[sd - 1])):
            entity_ids[sd - 1][i] = list(range(cur, cur + pts_per_facet))
            cur += pts_per_facet

        # internal nodes, if applicable
        entity_ids[sd] = {0: []}
        if degree > 0:
            num_internal_nodes = expansions.polynomial_dimension(
                ref_el, degree - 1)
            entity_ids[sd][0] = list(range(cur, cur + num_internal_nodes * sd))

        super(RTDualSet, self).__init__(nodes, ref_el, entity_ids)
Beispiel #10
0
def NedelecSpace3D(ref_el, k):
    """Constructs a nodal basis for the 3d first-kind Nedelec space"""
    sd = ref_el.get_spatial_dimension()
    if sd != 3:
        raise Exception("NedelecSpace3D requires 3d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd, ))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    if k > 0:
        dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)
    else:
        dimPkm1 = 0

    vec_Pk_indices = list(
        chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk) for i in range(sd))))
    vec_Pk = vec_Pkp1.take(vec_Pk_indices)

    vec_Pke_indices = list(
        chain(*(range(i * dimPkp1 + dimPkm1, i * dimPkp1 + dimPk)
                for i in range(sd))))

    vec_Pke = vec_Pkp1.take(vec_Pke_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)

    Q = quadrature.make_quadrature(ref_el, 2 * (k + 1))

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkCrossXcoeffs = numpy.zeros(
        (vec_Pke.get_num_members(), sd, Pkp1.get_num_members()), "d")

    Pke_qpts = vec_Pke.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    for i in range(vec_Pke.get_num_members()):
        for j in range(sd):  # vector components
            qwts_cur_bf_val = (
                Qpts[:, (j + 2) % 3] * Pke_qpts[i, (j + 1) % 3, :] -
                Qpts[:, (j + 1) % 3] * Pke_qpts[i, (j + 2) % 3, :]) * Qwts
            PkCrossXcoeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, qwts_cur_bf_val)


#            for k in range( Pkp1.get_num_members() ):
#                 PkCrossXcoeffs[i,j,k] = sum( Qwts * cur_bf_val * Pkp1_at_Qpts[k,:] )
#                for l in range( len( Qpts ) ):
#                    cur_bf_val = Qpts[l][(j+2)%3] \
#                                 * Pke_qpts[i,(j+1)%3,l] \
#                                 - Qpts[l][(j+1)%3] \
#                                 * Pke_qpts[i,(j+2)%3,l]
#                    PkCrossXcoeffs[i,j,k] += Qwts[l] \
#                                             * cur_bf_val \
#                                             * Pkp1_at_Qpts[k,l]

    PkCrossX = polynomial_set.PolynomialSet(ref_el, k + 1, k + 1,
                                            vec_Pkp1.get_expansion_set(),
                                            PkCrossXcoeffs,
                                            vec_Pkp1.get_dmats())
    return polynomial_set.polynomial_set_union_normalized(vec_Pk, PkCrossX)
Beispiel #11
0
def NedelecSpace2D(ref_el, k):
    """Constructs a basis for the 2d H(curl) space of the first kind
    which is (P_k)^2 + P_k rot( x )"""
    sd = ref_el.get_spatial_dimension()
    if sd != 2:
        raise Exception("NedelecSpace2D requires 2d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd, ))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)

    vec_Pk_indices = list(
        chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk) for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * k + 2)

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkH_crossx_coeffs = numpy.zeros(
        (PkH.get_num_members(), sd, Pkp1.get_num_members()), "d")

    def rot_x_foo(a):
        if a == 0:
            return 1, 1.0
        elif a == 1:
            return 0, -1.0

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            (ind, sign) = rot_x_foo(j)
            for k in range(Pkp1.get_num_members()):
                PkH_crossx_coeffs[i, j, k] = sign * sum(
                    Qwts * PkH_at_Qpts[i, :] * Qpts[:, ind] *
                    Pkp1_at_Qpts[k, :])


#                for l in range( len( Qpts ) ):
#                    PkH_crossx_coeffs[i,j,k] += Qwts[ l ] \
#                                                * PkH_at_Qpts[i,l] \
#                                                * Qpts[l][ind] \
#                                                * Pkp1_at_Qpts[k,l] \
#                                                * sign

    PkHcrossx = polynomial_set.PolynomialSet(ref_el, k + 1, k + 1,
                                             vec_Pkp1.get_expansion_set(),
                                             PkH_crossx_coeffs,
                                             vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(
        vec_Pk_from_Pkp1, PkHcrossx)
Beispiel #12
0
def NedelecSpace3D(ref_el, k):
    """Constructs a nodal basis for the 3d first-kind Nedelec space"""
    sd = ref_el.get_spatial_dimension()
    if sd != 3:
        raise Exception("NedelecSpace3D requires 3d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    if k > 0:
        dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)
    else:
        dimPkm1 = 0

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk = vec_Pkp1.take(vec_Pk_indices)

    vec_Pke_indices = list(chain(*(range(i * dimPkp1 + dimPkm1, i * dimPkp1 + dimPk)
                                   for i in range(sd))))

    vec_Pke = vec_Pkp1.take(vec_Pke_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)

    Q = quadrature.make_quadrature(ref_el, 2 * (k + 1))

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkCrossXcoeffs = numpy.zeros((vec_Pke.get_num_members(),
                                  sd,
                                  Pkp1.get_num_members()), "d")

    Pke_qpts = vec_Pke.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    for i in range(vec_Pke.get_num_members()):
        for j in range(sd):  # vector components
            qwts_cur_bf_val = (
                Qpts[:, (j + 2) % 3] * Pke_qpts[i, (j + 1) % 3, :] -
                Qpts[:, (j + 1) % 3] * Pke_qpts[i, (j + 2) % 3, :]) * Qwts
            PkCrossXcoeffs[i, j, :] = numpy.dot(Pkp1_at_Qpts, qwts_cur_bf_val)
#            for k in range( Pkp1.get_num_members() ):
#                 PkCrossXcoeffs[i,j,k] = sum( Qwts * cur_bf_val * Pkp1_at_Qpts[k,:] )
#                for l in range( len( Qpts ) ):
#                    cur_bf_val = Qpts[l][(j+2)%3] \
#                                 * Pke_qpts[i,(j+1)%3,l] \
#                                 - Qpts[l][(j+1)%3] \
#                                 * Pke_qpts[i,(j+2)%3,l]
#                    PkCrossXcoeffs[i,j,k] += Qwts[l] \
#                                             * cur_bf_val \
#                                             * Pkp1_at_Qpts[k,l]

    PkCrossX = polynomial_set.PolynomialSet(ref_el,
                                            k + 1,
                                            k + 1,
                                            vec_Pkp1.get_expansion_set(),
                                            PkCrossXcoeffs,
                                            vec_Pkp1.get_dmats())
    return polynomial_set.polynomial_set_union_normalized(vec_Pk, PkCrossX)
Beispiel #13
0
def NedelecSpace2D(ref_el, k):
    """Constructs a basis for the 2d H(curl) space of the first kind
    which is (P_k)^2 + P_k rot( x )"""
    sd = ref_el.get_spatial_dimension()
    if sd != 2:
        raise Exception("NedelecSpace2D requires 2d reference element")

    vec_Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1, (sd,))

    dimPkp1 = expansions.polynomial_dimension(ref_el, k + 1)
    dimPk = expansions.polynomial_dimension(ref_el, k)
    dimPkm1 = expansions.polynomial_dimension(ref_el, k - 1)

    vec_Pk_indices = list(chain(*(range(i * dimPkp1, i * dimPkp1 + dimPk)
                                  for i in range(sd))))
    vec_Pk_from_Pkp1 = vec_Pkp1.take(vec_Pk_indices)

    Pkp1 = polynomial_set.ONPolynomialSet(ref_el, k + 1)
    PkH = Pkp1.take(list(range(dimPkm1, dimPk)))

    Q = quadrature.make_quadrature(ref_el, 2 * k + 2)

    Qpts = numpy.array(Q.get_points())
    Qwts = numpy.array(Q.get_weights())

    zero_index = tuple([0 for i in range(sd)])

    PkH_at_Qpts = PkH.tabulate(Qpts)[zero_index]
    Pkp1_at_Qpts = Pkp1.tabulate(Qpts)[zero_index]

    PkH_crossx_coeffs = numpy.zeros((PkH.get_num_members(),
                                     sd,
                                     Pkp1.get_num_members()), "d")

    def rot_x_foo(a):
        if a == 0:
            return 1, 1.0
        elif a == 1:
            return 0, -1.0

    for i in range(PkH.get_num_members()):
        for j in range(sd):
            (ind, sign) = rot_x_foo(j)
            for k in range(Pkp1.get_num_members()):
                PkH_crossx_coeffs[i, j, k] = sign * sum(Qwts * PkH_at_Qpts[i, :] * Qpts[:, ind] * Pkp1_at_Qpts[k, :])
#                for l in range( len( Qpts ) ):
#                    PkH_crossx_coeffs[i,j,k] += Qwts[ l ] \
#                                                * PkH_at_Qpts[i,l] \
#                                                * Qpts[l][ind] \
#                                                * Pkp1_at_Qpts[k,l] \
#                                                * sign

    PkHcrossx = polynomial_set.PolynomialSet(ref_el,
                                             k + 1,
                                             k + 1,
                                             vec_Pkp1.get_expansion_set(),
                                             PkH_crossx_coeffs,
                                             vec_Pkp1.get_dmats())

    return polynomial_set.polynomial_set_union_normalized(vec_Pk_from_Pkp1,
                                                          PkHcrossx)