Ejemplo n.º 1
0
    def __init__( self , ref_el , degree ):
        sd = ref_el.get_spatial_dimension()
        if sd != 2:
            raise Exception("Nedelec2D only works on triangles")

        nodes = []

        t = ref_el.get_topology()

        num_edges = len( t[1] )

        # edge tangents
        for i in range( num_edges ):
            pts_cur = ref_el.make_points( 1 , i , degree + 2 )
            for j in range( len( pts_cur ) ):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation( ref_el , \
                                                           i , pt_cur )
                nodes.append( f )

        # internal moments
        if degree > 0:
            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,) )
                    nodes.append( l_cur )


        entity_ids = {}

        # set to empty
        for i in range( sd + 1 ):
            entity_ids[i] = {}
            for j in range( len( t[i] ) ):
                entity_ids[i][j] = []

        cur = 0

        # edges
        num_edge_pts = len( ref_el.make_points( 1 , 0 , degree + 2 ) )

        for i in range( len( t[1] ) ):
            entity_ids[1][i] = list(range( cur , cur + num_edge_pts))
            cur += num_edge_pts

        # moments against P_{degree-1} internally, if degree > 0
        if degree > 0:
            num_internal_dof = sd * Pkm1_at_qpts.shape[0]
            entity_ids[2][0] = list(range( cur , cur + num_internal_dof))

        dual_set.DualSet.__init__( self , nodes , ref_el , entity_ids )
Ejemplo n.º 2
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 = reduce( lambda a,b: a + b , \
                             [ list(range( i * dimPkp1 , i * dimPkp1+dimPk)) \
                               for i in range(sd) ] )
    vec_Pk = vec_Pkp1.take( vec_Pk_indices )


    vec_Pke_indices = reduce( lambda a,b : a + b , \
                              [ list(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 ]

    import time
    t = time.time()
    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 )
Ejemplo n.º 3
0
    def __init__( self , ref_el , degree ):
        sd = ref_el.get_spatial_dimension()
        if sd != 3:
            raise Exception("NedelecDual3D only works on tetrahedra")

        nodes = []

        t = ref_el.get_topology()

        # how many edges
        num_edges = len( t[1] )

        for i in range( num_edges ):
            # points to specify P_k on each edge
            pts_cur = ref_el.make_points( 1 , i , degree + 2 )
            for j in range( len( pts_cur ) ):
                pt_cur = pts_cur[j]
                f = functional.PointEdgeTangentEvaluation( ref_el , \
                                                           i , pt_cur )
                nodes.append( f )

        if degree > 0: # face tangents
            num_faces = len( t[2] )
            for i in range( num_faces ): # loop over faces
                pts_cur = ref_el.make_points( 2 , i , degree + 2 )
                for j in range( len( pts_cur ) ): # loop over points
                    pt_cur = pts_cur[j]
                    for k in range(2): # loop over tangents
                        f = functional.PointFaceTangentEvaluation( ref_el , \
                                                                   i , k , \
                                                                   pt_cur )
                        nodes.append( f )

        if degree > 1: # internal moments
            Q = quadrature.make_quadrature( ref_el , 2 * ( degree + 1 ) )
            qpts = Q.get_points()
            Pkm2 = polynomial_set.ONPolynomialSet( ref_el , degree - 2 )
            zero_index = tuple( [ 0 for i in range( sd ) ] )
            Pkm2_at_qpts = Pkm2.tabulate( qpts )[ zero_index ]

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


        entity_ids = {}
        # set to empty
        for i in range( sd + 1 ):
            entity_ids[i] = {}
            for j in range( len( t[i] ) ):
                entity_ids[i][j] = []

        cur = 0

        # edge dof
        num_pts_per_edge = len( ref_el.make_points( 1 , 0 , degree + 2 ) )
        for i in range( len( t[1] ) ):
            entity_ids[1][i] = list(range( cur , cur + num_pts_per_edge))
            cur += num_pts_per_edge

        # face dof
        if degree > 0:
            num_pts_per_face = len( ref_el.make_points( 2 , 0 , degree + 2 ) )
            for i in range( len( t[2] ) ):
                entity_ids[2][i] = list(range( cur , cur + 2 * num_pts_per_face))
                cur += 2 * num_pts_per_face

        if degree > 1:
            num_internal_dof = Pkm2_at_qpts.shape[0] * sd
            entity_ids[3][0] = list(range( cur , cur + num_internal_dof))


        dual_set.DualSet.__init__( self , nodes , ref_el , entity_ids )
Ejemplo n.º 4
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 = reduce( lambda a,b: a+b , \
                             [ list(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 )
Ejemplo n.º 5
0
 def __init__(self, ref_el):
     poly_set = polynomial_set.ONPolynomialSet(ref_el, 5)
     dual = QuinticArgyrisDualSet(ref_el)
     finite_element.FiniteElement.__init__(self, poly_set, dual, 5)
Ejemplo n.º 6
0
 def __init__(self, ref_el, degree):
     poly_set = polynomial_set.ONPolynomialSet(ref_el, degree)
     dual = ArgyrisDualSet(ref_el, degree)
     finite_element.FiniteElement.__init__(self, poly_set, dual, degree)
Ejemplo n.º 7
0
 def __init__( self , ref_el ):
     poly_set = polynomial_set.ONPolynomialSet( ref_el , 0 )
     dual = P0Dual( ref_el )
     finite_element.FiniteElement.__init__( self , poly_set , dual , 0 )