Example #1
0
def test_displacement_discontinuity_derivative():
    bf = basis_from_degree(1)
    msh = simple_line_mesh(2)
    qs = QuadStrategy(msh, 10, 10, 10, 10)
    apply_to_elements(msh, "basis", bf, non_gen = True)
    apply_to_elements(msh, "continuous", True, non_gen = True)
    apply_to_elements(msh, "qs", qs, non_gen = True)
    init_dofs(msh)

    k_rh = RegularizedHypersingularKernel(1.0, 0.25)

    # basis function should be equal to x_hat
    k = 1
    i = 1
    qi = qs.get_simple()
    strength = ConstantBasis([1.0, 1.0])
    k_rh.set_interior_data(np.array([-2.0, 0.0]), np.array([0.0, 1.0]))
    basis = bf.get_gradient_basis()
    result = single_integral(msh.elements[k].mapping.eval, k_rh, strength,
                    basis, qi, 0, i)
    np.testing.assert_almost_equal(result[1][1], 0.193011, 4)
    np.testing.assert_almost_equal(result[0][0], -0.0191957, 4)

    i = 0
    result = single_integral(msh.elements[k].mapping.eval, k_rh, strength,
                    basis, qi, 0, i)
    np.testing.assert_almost_equal(result[1][1], -0.193011, 4)
    np.testing.assert_almost_equal(result[0][0], 0.0191957, 4)

    strlocnorm = [((1.0, 0.0), np.array([-2.0, 0.0]), np.zeros(2))]
    rhs = point_source_rhs(msh, strlocnorm, k_rh)
def test_improved_hypersingular():
    mesh = simple_line_mesh(1, (0, 0), (1, 0))
    mapping = PolynomialMapping(mesh.elements[0])
    degree = 7
    bf = gll_basis(degree)
    one = ConstantBasis(np.ones(2))

    quad_info_exact = gauss(100)

    a = 0.01
    b = 0.05

    mapped_ay = map_singular_pt(a, 0.0, 1.0)
    mapped_by = map_distance_to_interval(b, 0.0, 1.0)
    quad_deg = degree + 4

    moments_xa0_r0 = legendre.legendre_integrals(quad_deg)
    moments_xa0_r2 = modify_divide_r2(
        quad_deg, moments_xa0_r0, mapped_ay, mapped_by, mu_2_0(mapped_ay, mapped_by), mu_2_1(mapped_ay, mapped_by)
    )
    moments_xa0_r4 = modify_divide_r2(
        quad_deg, moments_xa0_r2, mapped_ay, mapped_by, mu_4_0(mapped_ay, mapped_by), mu_4_1(mapped_ay, mapped_by)
    )
    moments_xa0_r6 = modify_divide_r2(
        quad_deg, moments_xa0_r4, mapped_ay, mapped_by, mu_6_0(mapped_ay, mapped_by), mu_6_1(mapped_ay, mapped_by)
    )
    moments_xa1_r6 = modify_times_x_minus_a(len(moments_xa0_r6) - 2, moments_xa0_r6, mapped_ay)
    moments_xa2_r6 = modify_times_x_minus_a(len(moments_xa1_r6) - 2, moments_xa1_r6, mapped_ay)
    moments_xa3_r6 = modify_times_x_minus_a(len(moments_xa2_r6) - 2, moments_xa2_r6, mapped_ay)
    moments_xa4_r6 = modify_times_x_minus_a(len(moments_xa3_r6) - 2, moments_xa3_r6, mapped_ay)

    est = [[0, 0], [0, 0]]
    x, w = recursive_quad(moments_xa0_r6[: degree + 1])
    x, w = map_pts_wts(x, w, 0.0, 1.0)
    w = map_weights_by_inv_power(w, 6.0, 0.0, 1.0) * ((-b / 2) ** 2) * ((-2 * b) ** 2)
    est[1][1] = w[0]

    x, w = recursive_quad(moments_xa1_r6[: degree + 1])
    x, w = map_pts_wts(x, w, 0.0, 1.0)
    w = map_weights_by_inv_power(w, 6.0, 0.0, 1.0) * ((-b / 2) ** 2) * ((-2 * b) ** 1)
    est[0][1] = w[0]
    est[1][0] = w[0]
    x, w = recursive_quad(moments_xa2_r6[: degree + 1])
    x, w = map_pts_wts(x, w, 0.0, 1.0)
    w = map_weights_by_inv_power(w, 6.0, 0.0, 1.0) * ((-b / 2) ** 2) * ((-2 * b) ** 0)
    est[0][0] = w[0]

    # qi = QuadratureInfo(a, x, w)

    kernelv1 = HypersingularPart1V1()
    kernelv2 = HypersingularPart1V2()

    pt = [a, b]
    normal = [0.0, 1.0]
    kernelv1.set_interior_data(pt, normal)
    kernelv2.set_interior_data(pt, normal)

    integrate = lambda qi, k: single_integral(mapping.eval, k, one, bf, qi, 0, 0)
    exact = integrate(quad_info_exact, kernelv1)
    np.testing.assert_almost_equal(np.array(exact), np.array(est), 10)
Example #3
0
def single_integral_wrapper(map_eval, kernel, basis, quad_info, which_fnc):
    """
    A wrapper so that single integral has the interface expected by the
    interior point computation functions.
    """
    return single_integral(map_eval, kernel, one,
                           basis, quad_info, 0, which_fnc)
Example #4
0
def test_M_integral_diff_dof():
    msh = simple_line_mesh(2)
    q = quadrature.gauss(2)
    bf = basis_funcs.basis_from_degree(1)
    kernel = MassMatrixKernel(0, 0)
    M_local = single_integral(msh.elements[0].mapping.eval, kernel, bf,
          bf, q, 0, 1)
    # integral of (1-x)*x from 0 to 1
    np.testing.assert_almost_equal(M_local[0][0], 1.0 / 6.0)
Example #5
0
def test_M_integral_same_dof_with_jacobian():
    msh = simple_line_mesh(4)
    q = quadrature.gauss(2)
    bf = basis_funcs.basis_from_degree(1)
    kernel = MassMatrixKernel(0, 0)
    M_local = single_integral(msh.elements[0].mapping.eval, kernel, bf,
                              bf, q, 0, 0)
    # Element size divided by two so the M value should be divided by two
    np.testing.assert_almost_equal(M_local[0][0], 1.0 / 6.0)
def test_telles_quad_strategy():
    msh = simple_line_mesh(4)
    tqs = TellesQuadStrategy(4)
    qi = tqs.get_interior_quadrature(msh.elements[3], [0.0, 0.0])

    kernel = TractionKernel(1.0, 0.25)
    one = ConstantBasis((1.0, 1.0))
    est = single_integral(msh.elements[3].mapping.eval,
                          kernel, one, one, qi, 0, 0)
    exact = -0.0367726
    np.testing.assert_almost_equal(exact, est[0][1])
Example #7
0
def test_plot_single_integral_kernel():
    msh = simple_line_mesh(2)
    x = np.linspace(0.0, 1, 1000)
    kernel = TractionKernel(1.0, 0.25)
    bf = basis_funcs.basis_from_degree(8)
    bf1 = ConstantBasis((1.0, 1.0))
    k = np.zeros_like(x)
    k_int = np.zeros_like(x)
    for (i, x_val) in enumerate(x):
        q = quadrature.piessens(16, x_val, 16)
        kernel.set_interior_data([x_val, 0.0], [0.0,1.0])
        kd = kernel.get_interior_integral_data([1.0, 0.0], [0.0, 1.0])
        k[i] = kernel._call(kd, 0, 1)
        k_int[i] = single_integral(msh.elements[1].mapping.eval, kernel, bf1,
                                bf, q, 0, 4)[0][1]
def test_fast_lobatto():
    N = 15
    mesh = simple_line_mesh(1, (0, 0), (1, 0))
    mapping = PolynomialMapping(mesh.elements[0])
    kernel = TractionKernel(1.0, 0.25)
    bf = gll_basis(N)
    one = ConstantBasis(np.ones(2))
    quad_info_old = lobatto(N + 1)
    pt = [0.0, -5.0]
    normal = [0.0, 1.0]

    kernel.set_interior_data(pt, normal)
    est_slow = single_integral(mapping.eval, kernel, one, bf, quad_info_old, 0, 0)
    est_fast = aligned_single_integral(mapping.eval, kernel, bf, quad_info_old, 0)
    np.testing.assert_almost_equal(np.array(est_slow), np.array(est_fast))
Example #9
0
def _element_mass(matrix, e_k):
    # Because the term is identical (just replace u by t) for both
    # integral equations, this function does not care about the BC type
    bc_basis = e_k.bc.basis
    if type(bc_basis) is ZeroBasis:
        return

    q_info = e_k.qs.get_nonsingular_minpts()
    kernel = MassMatrixKernel(0, 0)
    for i in range(e_k.basis.n_fncs):
        for j in range(bc_basis.n_fncs):
            M_local = single_integral(e_k.mapping.eval,
                              kernel,
                              e_k.basis,
                              bc_basis,
                              q_info,
                              i, j)
            matrix[e_k.dofs[0, i], e_k.dofs[0, j]] += M_local[0][0]
            matrix[e_k.dofs[1, i], e_k.dofs[1, j]] += M_local[1][1]
def test_gauss_displacement_xy():
    mesh = simple_line_mesh(1, (0, 0), (1, 0))
    mapping = PolynomialMapping(mesh.elements[0])
    kernel = TractionKernel(1.0, 0.25)
    degree = 4
    bf = gll_basis(degree)
    one = ConstantBasis(np.ones(2))
    quad_info_exact = gauss(100)
    quad_info = lobatto(degree + 1)

    # Testing GLL basis and quadrature combination on the nonsingular part
    # of the displacement kernel.
    pt = [0.5, 1000.0]
    normal = [0.0, 1.0]
    kernel.set_interior_data(pt, normal)

    integrate = lambda qi: single_integral(mapping.eval, kernel, one, bf, qi, 0, 0)
    exact = integrate(quad_info_exact)
    est = integrate(quad_info)
    np.testing.assert_almost_equal(exact[0][1], est[0][1], 16)
def test_rl_integral():
    mesh = simple_line_mesh(1, (0, 0), (1, 0))
    mapping = PolynomialMapping(mesh.elements[0])
    kernel = TractionKernel(1.0, 0.25)
    bf = gll_basis(4)
    one = ConstantBasis(np.ones(2))

    quad_info_old = lobatto(5)
    x_bf = np.array(bf.nodes)
    x_q = np.array(quad_info_old.x)
    distance = 5.0
    quad_info_new = rl_quad(5, 0.0, distance)
    # This one is comparing lobatto quadrature and recursive legendre quadrature
    # on the TractionKernel which is 1/r singular.

    pt = [0.0, -distance]
    normal = [0.0, 1.0]

    # exact = 0.2473475767
    exact = 0.00053055607635

    integrate = lambda qi: single_integral(mapping.eval, kernel, one, bf, qi, 0, 0)
    aligned_integrate = lambda qi: aligned_single_integral(mapping.eval, kernel, bf, qi, 0)

    kernel.set_interior_data(pt, normal)
    est_gauss = integrate(quad_info_old)
    np.testing.assert_almost_equal(est_gauss[0][0], exact)
    est_gauss_fast = aligned_integrate(quad_info_old)
    np.testing.assert_almost_equal(est_gauss_fast[0][0], exact)

    # This stuff doesn't work yet
    est_new = integrate(quad_info_new)
    np.testing.assert_almost_equal(est_new[0][0], exact, 6)

    est_new_fast = aligned_integrate(quad_info_new)
    np.testing.assert_almost_equal(est_new_fast[0][0], exact, 6)
Example #12
0
def _element_pair(matrix, e_k, e_l, which_kernels, rhs_or_matrix):
    # Determine whether to use the boundary condition or the solution basis
    # as the inner basis function
    if rhs_or_matrix == "rhs":
        init_e_l_basis = e_l.bc.basis
    else:
        init_e_l_basis = e_l.basis

    # If either of the bases are the zero basis, then don't compute
    # anything
    if type(e_k.basis) is ZeroBasis or \
       type(init_e_l_basis) is ZeroBasis:
        return

    # Determine which kernel and which bases to use
    kernel, factor = which_kernels[e_k.bc.type][e_l.bc.type][rhs_or_matrix]
    if kernel is None:
        return

    # Decide whether to use the basis or its gradient
    e_k_basis, e_k_pt_srcs = _choose_basis(e_k.basis, kernel.test_gradient)
    e_l_basis, e_l_pt_srcs = _choose_basis(init_e_l_basis, kernel.soln_gradient)

    # Now that we might have taken a derivative, check for ZeroBases again.
    if type(e_k_basis) is ZeroBasis:
        return

    # Determine what quadrature formula to use
    quad_outer, quad_inner = e_k.qs.get_quadrature(
                            kernel.singularity_type, e_k, e_l)


    # Handle point sources
    # Filter out the point sources that we can safely ignore
    # many of these will be ignored because there will be an equal and
    # opposite point source contribution from the adjacent element.
    # TODO!
    # Currently, I ignore all point source on the test function side
    # of the problem, because these should be handled by the continuity
    # of the displacement field. I should probably think about this
    # a bit more...
    e_k_pt_srcs = [[],[]]

    # This probably explains some of the problems I was having with the
    # constant traction crack problem.

    # I also ignore all point source if we are dealing
    if rhs_or_matrix == "matrix":
        e_l_pt_srcs = [[],[]]

    # Loop over point sources and integrate!
    # All cross multiplications are necessary.
    # the pt sources are tuples like ((node, str_x, str_y), local_dof)
    # for e_k_pt in e_k_pt_srcs:
    #     phys_pt_k = e_k.mapping.get_physical_point(e_k_pt[0][0])
    #     kernel.set_interior_data(phys_pt_k,
    #     for j in range(e_l.basis.n_fncs):
    #         pass
    #     for e_l_pt in e_k_pt_srcs:
    #         phys_pt_l = e_l.mapping.get_physical_point(e_l_pt[0][0])

    e_l_pt_left = None
    e_l_pt_right = None
    if e_l_pt_srcs != [[],[]] and (e_l.neighbors_left == [] or e_l.neighbors_left[0].bc.type != 'traction'):
        e_l_pt_left = e_l_pt_srcs[0][0]
    if e_l_pt_srcs != [[],[]] and (e_l.neighbors_right == [] or e_l.neighbors_right[0].bc.type != 'traction'):
        e_l_pt_right = e_l_pt_srcs[0][1]

    for i in range(e_k.basis.n_fncs):
        for pt_src_idx, e_l_pt in enumerate([e_l_pt_left, e_l_pt_right]):
            if e_l_pt is None:
                continue
            e_l_dof = e_l_pt_srcs[1][pt_src_idx]
            phys_pt_l = e_l.mapping.get_physical_point(e_l_pt[0])
            normal_l = e_l.mapping.get_normal(e_l_pt[0])
            strength = ConstantBasis([e_l_pt[1], e_l_pt[2]])
            kernel.set_interior_data(phys_pt_l, normal_l)
            integral = single_integral(e_k.mapping.eval,
                                   kernel,
                                   e_k_basis,
                                   strength,
                                   quad_outer,
                                   i, 0)
            for idx1 in range(2):
                for idx2 in range(2):
                    matrix[e_k.dofs[idx1, i], e_l.dofs[idx2, e_l_dof]] += \
                        factor * integral[idx1][idx2]

    if type(e_l_basis) is ZeroBasis:
        return

    # Handle the integration of pairs of basis functions
    for i in range(e_k.basis.n_fncs):
        for j in range(e_l.basis.n_fncs):
            integral = \
                double_integral(e_k.mapping.eval, e_l.mapping.eval,
                                kernel, e_k_basis, e_l_basis,
                                quad_outer, quad_inner, i, j)

            # Add the integrated term in the appropriate location
            for idx1 in range(2):
                for idx2 in range(2):
                    matrix[e_k.dofs[idx1, i], e_l.dofs[idx2, j]] +=\
                            factor * integral[idx1][idx2]