Example #1
0
def test_bspline(control, knots):  # SEEMS TO WORK?
    """
     Test if Cubic Spline created from object CubicSpline equals the sum of the control points
    and basis functions as in section 1.5
    """
    cubsplin = CubicSpline(control, knots)

    size = 10000
    bspline = zeros((size, 2))
    basis_functions = array(
        [basis_function(size, knots, j) for j in range(len(knots) - 2)])
    for u in range(size):
        bspline[u] = sum(control[i] * basis_functions[i, u]
                         for i in range(len(basis_functions)))

    plt.plot(cubsplin.get_spline()[:, 0],
             cubsplin.get_spline()[:, 1],
             'r',
             label="cubic spline")  # spline
    plt.plot(bspline[:, 0], bspline[:, 1], 'b', label="bspline")  # spline
    # plt.plot(control[:, 0], control[:, 1], '-.r', label="control polygon")  # control polygon
    # plt.scatter(control[:, 0], control[:, 1], color='red')  # de Boor points

    plt.title("B-Spline")
    plt.legend()
    plt.xlabel("x")
    plt.ylabel("y")
    plt.grid()
    plt.show()
Example #2
0
    def test_bspline(self):  
        """
        Test if Cubic Spline created from object CubicSpline equals the sum of the control points
        and basis functions as in section 1.5
        """
        cubsplin = CubicSpline(self.test_control, self.test_knots)

        size = 10000
        bspline = zeros((size, 2))
        basis_functions = array([basis_function(size, self.test_knots, j) for j in range(len(self.test_knots) - 2)])
        for u in range(size):
            bspline[u] = sum(self.test_control[i] * basis_functions[i, u] for i in range(len(basis_functions)))

        assert_allclose(cubsplin.get_spline(), bspline)
Example #3
0
def test_basis_functions(knots):
    """
    Plot every basis function according to the given knots
    :param knots: (array)
    :return: None
    """

    size = 1000
    L = len(knots) - 3
    first_knot = knots[0]
    last_knot = knots[-1]
    xspace = linspace(first_knot, last_knot, size)

    for j in range(L + 1):
        temp_base = basis_function(size, knots, j)
        plt.plot(xspace, temp_base)

    plt.title("Basis functions from {} to {}".format("$u_0$",
                                                     "$u_{}$".format({L})))
    plt.xlabel("u")
    plt.grid()
    plt.show()
def assemble_fem ( x_num, x, element_num, element_node, quad_num, t, k_fun, \
  rhs_fun ):

    #*****************************************************************************80
    #
    ## ASSEMBLE_FEM assembles the finite element stiffness matrix.
    #
    #  Licensing:
    #
    #    This code is distributed under the GNU LGPL license.
    #
    #  Modified:
    #
    #    07 November 2014
    #
    #  Author:
    #
    #    John Burkardt
    #
    #  Parameters:
    #
    #    Input, integer X_NUM, the number of nodes.
    #
    #    Input, real X(X_NUM), the coordinates of nodes.
    #
    #    Input, integer ELEMENT_NUM, the number of elements.
    #
    #    Input, integer ELEMENT_NODE(2,ELEMENT_NUM);
    #    ELEMENT_NODE(I,J) is the global index of local node I in element J.
    #
    #    Input, integer QUAD_NUM, the number of quadrature points used in assembly.
    #
    #    Input, real T, the current time.
    #
    #    Input, real K_FUN(), a function to evaluate the heat conductivity.
    #
    #    Input, real RHS_FUN(), a function to evaluate the right hand side.
    #
    #    Output, sparse real A(X_NUM,X_NUM), the finite element stiffness matrix.
    #
    #    Output, real B(X_NUM), the right hand side.
    #
    #  Local parameters:
    #
    #    Local, real BI, DBIDX, the value of some basis function
    #    and its first derivative at a quadrature point.
    #
    #    Local, real BJ, DBJDX, the value of another basis
    #    function and its first derivative at a quadrature point.
    #
    from basis_function import basis_function
    from quadrature_set import quadrature_set
    from reference_to_physical import reference_to_physical
    import numpy as np
    #
    #  Initialize the arrays.
    #
    b = np.zeros(x_num)
    a = np.zeros((x_num, x_num))
    #
    #  Get the quadrature weights and nodes.
    #
    reference_w, reference_q = quadrature_set(quad_num)
    #
    #  Consider each ELEMENT.
    #
    for element in range(0, element_num):

        element_x = np.zeros(2)
        element_x[0] = x[element_node[0, element]]
        element_x[1] = x[element_node[1, element]]

        element_q = reference_to_physical ( element, element_node, x, quad_num, \
          reference_q )

        element_area = element_x[1] - element_x[0]

        element_w = np.zeros(quad_num)
        for quad in range(0, quad_num):
            element_w[quad] = (element_area / 2.0) * reference_w[quad]


#
#  Consider the QUAD-th quadrature point in the element.
#
        k_value = k_fun(quad_num, element_q, t)
        rhs_value = rhs_fun(quad_num, element_q, t)

        for quad in range(0, quad_num):
            #
            #  Consider the TEST-th test function.
            #
            #  We generate an integral for every node associated with an unknown.
            #
            for i in range(0, 2):

                test = element_node[i, element]

                bi, dbidx = basis_function(test, element, x, element_q[quad])

                b[test] = b[test] + element_w[quad] * rhs_value[quad] * bi
                #
                #  Consider the BASIS-th basis function, which is used to form the
                #  value of the solution function.
                #
                for j in range(0, 2):

                    basis = element_node[j, element]

                    bj, dbjdx = basis_function(basis, element, x,
                                               element_q[quad])

                    a[test,basis] = a[test,basis] + element_w[quad] * ( \
                      + k_value[quad] * dbidx * dbjdx )

    return a, b
Example #5
0
def assemble_mass ( node_num, node_x, element_num, element_node, quad_num ):

#*****************************************************************************80
#
## ASSEMBLE_MASS assembles the finite element mass matrix.
#
#  Licensing:
#
#    This code is distributed under the GNU LGPL license.
#
#  Modified:
#
#    07 November 2014
#
#  Author:
#
#    John Burkardt
#
#  Parameters:
#
#    Input, integer NODE_NUM, the number of nodes.
#
#    Input, real NODE_X(NODE_NUM), the coordinates of nodes.
#
#    Input, integer ELEMENT_NUM, the number of elements.
#
#    Input, integer ELEMENT_NODE(2,ELEMENT_NUM);
#    ELEMENT_NODE(I,J) is the global index of local node I in element J.
#
#    Input, integer QUAD_NUM, the number of quadrature points used in assembly.
#
#    Output, sparse real C(NODE_NUM,NODE_NUM), the finite element mass matrix.
#
#  Local parameters:
#
#    Local, real BI, DBIDX, the value of some basis function
#    and its first derivative at a quadrature point.
#
#    Local, real BJ, DBJDX, the value of another basis
#    function and its first derivative at a quadrature point.
#
  from basis_function import basis_function
  from quadrature_set import quadrature_set
  from reference_to_physical import reference_to_physical
  import numpy as np
#
#  Initialize the arrays.
#
  c = np.zeros ( ( node_num, node_num ) )
#
#  Get the quadrature weights and nodes.
#
  reference_w, reference_q = quadrature_set ( quad_num )
#
#  Consider each ELEMENT.
#
  for element in range ( 0, element_num ):

    element_x = np.zeros ( 2 )
    element_x[0] = node_x[element_node[0,element]]
    element_x[1] = node_x[element_node[1,element]]

    element_q = reference_to_physical ( element, element_node, node_x, \
      quad_num, reference_q )

    element_area = element_x[1] - element_x[0]

    element_w = np.zeros ( quad_num )
    for quad in range ( 0, quad_num ):
      element_w[quad] = ( element_area / 2.0 ) * reference_w[quad]
#
#  Consider the QUAD-th quadrature point in the element.
#
    for quad in range ( 0, quad_num ):
#
#  Consider the TEST-th test function.
#
#  We generate an integral for every node associated with an unknown.
#
      for i in range ( 0, 2 ):

        test = element_node[i,element]

        bi, dbidx = basis_function ( test, element, node_x, element_q[quad] )
#
#  Consider the BASIS-th basis function, which is used to form the
#  value of the solution function.
#
        for j in range ( 0, 2 ):

          basis = element_node[j,element]

          bj, dbjdx = basis_function ( basis, element, node_x, element_q[quad] )

          c[test,basis] = c[test,basis] + element_w[quad] * bi * bj

  return c
def assemble_fem ( x_num, x, element_num, element_node, quad_num, t, k_fun, \
  rhs_fun ):

#*****************************************************************************80
#
## ASSEMBLE_FEM assembles the finite element stiffness matrix.
#
#  Licensing:
#
#    This code is distributed under the GNU LGPL license.
#
#  Modified:
#
#    07 November 2014
#
#  Author:
#
#    John Burkardt
#
#  Parameters:
#
#    Input, integer X_NUM, the number of nodes.
#
#    Input, real X(X_NUM), the coordinates of nodes.
#
#    Input, integer ELEMENT_NUM, the number of elements.
#
#    Input, integer ELEMENT_NODE(2,ELEMENT_NUM);
#    ELEMENT_NODE(I,J) is the global index of local node I in element J.
#
#    Input, integer QUAD_NUM, the number of quadrature points used in assembly.
#
#    Input, real T, the current time.
#
#    Input, real K_FUN(), a function to evaluate the heat conductivity.
#
#    Input, real RHS_FUN(), a function to evaluate the right hand side.
#
#    Output, sparse real A(X_NUM,X_NUM), the finite element stiffness matrix.
#
#    Output, real B(X_NUM), the right hand side.
#
#  Local parameters:
#
#    Local, real BI, DBIDX, the value of some basis function
#    and its first derivative at a quadrature point.
#
#    Local, real BJ, DBJDX, the value of another basis
#    function and its first derivative at a quadrature point.
#
  from basis_function import basis_function
  from quadrature_set import quadrature_set
  from reference_to_physical import reference_to_physical
  import numpy as np
#
#  Initialize the arrays.
#
  b = np.zeros ( x_num )
  a = np.zeros ( ( x_num, x_num ) )
#
#  Get the quadrature weights and nodes.
#
  reference_w, reference_q = quadrature_set ( quad_num )
#
#  Consider each ELEMENT.
#
  for element in range ( 0, element_num ):

    element_x = np.zeros ( 2 )
    element_x[0] = x[element_node[0,element]]
    element_x[1] = x[element_node[1,element]]

    element_q = reference_to_physical ( element, element_node, x, quad_num, \
      reference_q )

    element_area = element_x[1] - element_x[0]

    element_w = np.zeros ( quad_num )
    for quad in range ( 0, quad_num ):
      element_w[quad] = ( element_area / 2.0 ) * reference_w[quad]
#
#  Consider the QUAD-th quadrature point in the element.
#
    k_value = k_fun ( quad_num, element_q, t )
    rhs_value = rhs_fun ( quad_num, element_q, t )

    for quad in range ( 0, quad_num ):
#
#  Consider the TEST-th test function.
#
#  We generate an integral for every node associated with an unknown.
#
      for i in range ( 0, 2 ):

        test = element_node[i,element]

        bi, dbidx = basis_function ( test, element, x, element_q[quad] )

        b[test] = b[test] + element_w[quad] * rhs_value[quad] * bi
#
#  Consider the BASIS-th basis function, which is used to form the
#  value of the solution function.
#
        for j in range ( 0, 2 ):

          basis = element_node[j,element]

          bj, dbjdx = basis_function ( basis, element, x, element_q[quad] )

          a[test,basis] = a[test,basis] + element_w[quad] * ( \
            + k_value[quad] * dbidx * dbjdx )

  return a, b