Beispiel #1
0
def simple_rhs_assemble(mesh, f_grabber, kernel):
    rhs = np.zeros(mesh.total_dofs)
    for e_k in mesh:
        rhs_k_basis = (e_k.basis if not kernel.test_gradient
                       else e_k.basis.get_gradient_basis())
        for i in range(e_k.basis.n_fncs):
            for e_l in mesh:
                rhs_l_basis = f_grabber(e_l)
                rhs_l_basis = (rhs_l_basis if not kernel.soln_gradient
                               else rhs_l_basis.get_gradient_basis())
                (quad_outer, quad_inner) = e_k.qs.get_quadrature(
                                            kernel.singularity_type, e_k, e_l)
                for j in range(e_l.basis.n_fncs):
                    value = fl.double_integral(
                                    e_k.mapping.eval,
                                    e_l.mapping.eval,
                                    kernel,
                                    rhs_k_basis,
                                    rhs_l_basis,
                                    quad_outer, quad_inner,
                                    i, j)
                    rhs[e_k.dofs[0, i]] += value[0][0]
                    rhs[e_k.dofs[0, i]] += value[0][1]
                    rhs[e_k.dofs[1, i]] += value[1][0]
                    rhs[e_k.dofs[1, i]] += value[1][1]
    return rhs
Beispiel #2
0
def test_realistic_double_integral_symmetry():
    msh = simple_line_mesh(2)
    bf = basis_funcs.basis_from_degree(1)
    qs = quad_strategy.QuadStrategy(msh, 10, 10, 10, 10)
    kernel = DisplacementKernel(1.0, 0.25)

    # fnc = lambda r, n: 1 / r[0]
    one = double_integral(msh.elements[1].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                          bf, qs.get_simple(),
                          qs.quad_logr, 0, 1)

    two = double_integral(msh.elements[1].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                          bf, qs.get_simple(),
                          qs.quad_logr, 1, 0)
    one = np.array(one)
    two = np.array(two)
    np.testing.assert_almost_equal(one, two)
Beispiel #3
0
def test_exact_dbl_integrals_H_same_element():
    msh = simple_line_mesh(1)
    qs = quad_strategy.QuadStrategy(msh, 10, 10, 10, 10)
    qo = qs.get_simple()
    qi = qs.quad_oneoverr
    bf = basis_funcs.basis_from_degree(1)

    kernel = TractionKernel(1.0, 0.25)
    H_00 = double_integral(msh.elements[0].mapping.eval,
                           msh.elements[0].mapping.eval,
                           kernel,
                           bf, bf, qo,
                           qi, 0, 0)
    np.testing.assert_almost_equal(H_00, np.zeros((2, 2)), 3)

    H_11 = double_integral(msh.elements[0].mapping.eval,
                           msh.elements[0].mapping.eval,
                           kernel,
                           bf, bf, qo,
                           qi, 1, 1)
    np.testing.assert_almost_equal(H_11, np.zeros((2, 2)), 3)

    H_01 = double_integral(msh.elements[0].mapping.eval,
                           msh.elements[0].mapping.eval,
                           kernel, bf,
                           bf, qo,
                           qi, 0, 1)
    H_01_exact = np.array([[0.0, 1 / (6 * np.pi)],
                           [-1 / (6 * np.pi), 0.0]])
    np.testing.assert_almost_equal(H_01, H_01_exact, 3)

    H_10 = double_integral(msh.elements[0].mapping.eval,
                           msh.elements[0].mapping.eval,
                           kernel, bf,
                           bf, qo,
                           qi, 1, 0)
    H_10_exact = np.array([[0.0, -1 / (6 * np.pi)],
                           [1 / (6 * np.pi), 0.0]])
    np.testing.assert_almost_equal(H_10, H_10_exact, 3)
Beispiel #4
0
def test_exact_dbl_integrals_G_different_element():
    msh = simple_line_mesh(2)
    bf = basis_funcs.basis_from_degree(1)
    qs = quad_strategy.QuadStrategy(msh, 10, 10, 10, 10)
    qo = qs.get_simple()
    qi = qs.quad_logr
    kernel = DisplacementKernel(1.0, 0.25)

    G_00 = double_integral(msh.elements[0].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                           bf, qo, qi, 0, 0)
    G_10 = double_integral(msh.elements[0].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                           bf, qo, qi, 1, 0)
    G_01 = double_integral(msh.elements[0].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                           bf, qo, qi, 0, 1)
    G_11 = double_integral(msh.elements[0].mapping.eval, msh.elements[1].mapping.eval, kernel, bf,
                           bf, qo, qi, 1, 1)

    np.testing.assert_almost_equal(G_10,
                                   [[0.02833119, 0], [0, 0.01506828]], 4)
    np.testing.assert_almost_equal(G_01,
                                   [[0.00663146, 0], [0, -0.00663146]], 4)
    np.testing.assert_almost_equal(G_00, [[0.0150739, 0], [0, 0.00181103]], 4)
    np.testing.assert_almost_equal(G_11, [[0.0150739, 0], [0, 0.00181103]], 4)
Beispiel #5
0
def test_exact_dbl_integrals_G_same_element():
    msh = simple_line_mesh(1)
    bf = basis_funcs.basis_from_degree(1)
    qs = quad_strategy.QuadStrategy(msh, 10, 10, 10, 10)
    qo = qs.get_simple()
    qi = qs.quad_logr
    kernel = DisplacementKernel(1.0, 0.25)
    G_00 = double_integral(msh.elements[0].mapping.eval,
            msh.elements[0].mapping.eval, kernel, bf,
                           bf, qo, qi, 0, 0)
    np.testing.assert_almost_equal(G_00, [[0.165187, 0], [0, 0.112136]], 4)
    G_10 = double_integral(msh.elements[0].mapping.eval,
            msh.elements[0].mapping.eval, kernel, bf,
                           bf, qo, qi, 1, 0)
    np.testing.assert_almost_equal(G_10, [[0.112136, 0], [0, 0.0590839]], 4)
    G_01 = double_integral(msh.elements[0].mapping.eval,
                msh.elements[0].mapping.eval, kernel, bf,
                           bf, qo, qi, 0, 1)
    np.testing.assert_almost_equal(G_01, [[0.112136, 0], [0, 0.0590839]], 4)
    G_11 = double_integral(msh.elements[0].mapping.eval,
                    msh.elements[0].mapping.eval, kernel, bf,
                           bf, qo, qi, 1, 1)
    np.testing.assert_almost_equal(G_11, [[0.165187, 0], [0, 0.112136]], 4)
def test_hypersingular_vs_regularized_across_elements():
    # The regularization is only valid for a continuous basis, so the
    # integrations will not be equal unless I account for both elements.
    k_rh = RegularizedHypersingularKernel(1.0, 0.25)
    k_sh = SemiRegularizedHypersingularKernel(1.0, 0.25)
    k_h = HypersingularKernel(1.0, 0.25)

    K = 30
    mesh = circular_mesh(K, 2.0)
    bf = basis_from_degree(2)
    grad_bf = bf.get_gradient_basis()
    qs = QuadStrategy(mesh, 10, 10, 10, 10)
    apply_to_elements(mesh, "basis", bf, non_gen = True)
    apply_to_elements(mesh, "continuous", True, non_gen = True)
    init_dofs(mesh)

    el1a = 15
    el1b = 14
    el2a = 25
    el2b = 26
    o_q, i_q = qs.get_quadrature('logr', mesh.elements[el1a], mesh.elements[el2a])
    o_q = o_q

    # Four integrals for this matrix term. Two choices of source element
    # and two choices of solution element.
    a1 = double_integral(mesh.elements[el1a].mapping.eval,
            mesh.elements[el2a].mapping.eval, k_rh,
            grad_bf, grad_bf,
                        o_q, i_q, 0, 2)

    a2 = double_integral(mesh.elements[el1a].mapping.eval,
            mesh.elements[el2b].mapping.eval, k_rh,
            grad_bf, grad_bf,
                        o_q, i_q, 0, 0)

    a3 = double_integral(mesh.elements[el1b].mapping.eval,
            mesh.elements[el2a].mapping.eval, k_rh,
            grad_bf, grad_bf, o_q, i_q, 2, 2)

    a4 = double_integral(mesh.elements[el1b].mapping.eval
            , mesh.elements[el2b].mapping.eval, k_rh,
            grad_bf, grad_bf, o_q, i_q, 2, 0)

    b1 = double_integral(mesh.elements[el1a].mapping.eval
            , mesh.elements[el2a].mapping.eval, k_h,
            bf, bf, o_q, i_q, 0, 2)

    b2 = double_integral(mesh.elements[el1a].mapping.eval
            , mesh.elements[el2b].mapping.eval, k_h,
            bf, bf, o_q, i_q, 0, 0)

    b3 = double_integral(mesh.elements[el1b].mapping.eval
            , mesh.elements[el2a].mapping.eval, k_h,
            bf, bf, o_q, i_q, 2, 2)

    b4 = double_integral(mesh.elements[el1b].mapping.eval
            , mesh.elements[el2b].mapping.eval, k_h,
            bf, bf, o_q, i_q, 2, 0)

    c1 = double_integral(mesh.elements[el1a].mapping.eval
            , mesh.elements[el2a].mapping.eval, k_sh,
            grad_bf, bf, o_q, i_q, 0, 2)

    c2 = double_integral(mesh.elements[el1a].mapping.eval
            , mesh.elements[el2b].mapping.eval, k_sh,
            grad_bf, bf, o_q, i_q, 0, 0)

    c3 = double_integral(mesh.elements[el1b].mapping.eval
            , mesh.elements[el2a].mapping.eval, k_sh,
            grad_bf, bf, o_q, i_q, 2, 2)

    c4 = double_integral(mesh.elements[el1b].mapping.eval
            , mesh.elements[el2b].mapping.eval, k_sh,
            grad_bf, bf, o_q, i_q, 2, 0)

    a = np.array(a1) + np.array(a2) + np.array(a3) + np.array(a4)
    b = np.array(b1) + np.array(b2) + np.array(b3) + np.array(b4)
    c = np.array(c1) + np.array(c2) + np.array(c3) + np.array(c4)
    np.testing.assert_almost_equal(a, b)
    np.testing.assert_almost_equal(b, c)
    np.testing.assert_almost_equal(a, c)
def test_hypersingular_vs_regularized():
    # By the regularization of the hypersingular integral, these two
    # integrations should give the same result.
    # I've left
    # LOTS OF DETECTIVE WORK!
    # in this function, because I had a fun (awful?) time figuring out
    # how to get these two integrations to match up... Took three (four?)
    # full days...
    # The integrations are only equal for an interior basis function. If
    # the basis function's support crosses two elements, the point n - 1
    # dimensional term in the integration by parts still influences the
    # result

    k_rh = RegularizedHypersingularKernel(1.0, 0.25)
    k_sh = SemiRegularizedHypersingularKernel(1.0, 0.25)
    k_h = HypersingularKernel(1.0, 0.25)

    K = 30
    mesh = circular_mesh(K, 2.0)
    bf = basis_from_degree(2)
    grad_bf = bf.get_gradient_basis()
    qs = QuadStrategy(mesh, 10, 10, 10, 10)
    apply_to_elements(mesh, "basis", bf, non_gen = True)
    apply_to_elements(mesh, "continuous", True, non_gen = True)
    init_dofs(mesh)

    el1 = 15
    # pp0 = mesh.get_physical_point(el1, 0.5)
    # m = mesh.get_normal(el1, 0.5)
    a = np.zeros((K, 2, 2))
    b = np.zeros((K, 2, 2))
    c = np.zeros((K, 2, 2))
    # qq = np.zeros((K, 2, 2))
    # cr1 = np.zeros(K)
    # cr2 = np.zeros(K)
    # n2x = np.zeros(K)
    # n2y = np.zeros(K)
    # grad2x = np.zeros(K)
    # grad2y = np.zeros(K)
    # k_rh_val = np.zeros((K, 2, 2))
    # k_h_val = np.zeros((K, 2, 2))
    for el2 in range(K):
        if np.abs(el2 - el1) < 2.5:
            continue
        i = 1
        j = 1
        o_q, i_q = qs.get_quadrature('logr', mesh.elements[el1], mesh.elements[el2])
        o_q = o_q
        a[el2, :, :] = double_integral(mesh.elements[el1].mapping.eval, mesh.elements[el2].mapping.eval, k_rh,
                                             grad_bf,
                                             grad_bf,
                                             o_q, i_q, i, j)
        b[el2, :, :] = double_integral(mesh.elements[el1].mapping.eval, mesh.elements[el2].mapping.eval, k_h,
                            bf, bf,
                            o_q, i_q, i, j)
        c[el2, :, :] = double_integral(mesh.elements[el1].mapping.eval, mesh.elements[el2].mapping.eval, k_sh,
                            grad_bf, bf,
                            o_q, i_q, i, j)
        # qq[el2, :, :] = double_integral(mesh, k_rh, bf, bf,
        #                     o_q, i_q, el1, 1, el2, 1)
        # # cr1[el2] = grad_bf.chain_rule(el1, 0.5)[0]
        # n2x[el2], n2y[el2] = mesh.get_normal(el2, 0.5)
        # grad2x[el2], grad2y[el2] = _get_deriv_point(mesh.basis_fncs.derivs,
        #                             mesh.coefficients,
        #                             el2,
        #                             0.5)
        # cr2[el2] = -n2x[el2] * grad2y[el2] + n2y[el2] * grad2x[el2]

        # pp = mesh.get_physical_point(el2, 0.5)
        # k_rh_val[el2, :, :] = \
        #         k_rh.call(pp - pp0, m, np.array([n2x[el2], n2y[el2]]))
        # k_h_val[el2, :, :] = \
        #         k_h.call(pp - pp0, m, np.array([n2x[el2], n2y[el2]]))

    # #easiest comparison
    # from matplotlib import pyplot as plt
    # plt.plot(range(K), a[:, 1, 1], label='ayy')
    # plt.plot(range(K), b[:, 1, 1], label='byy')
    # plt.plot(range(K), c[:, 1, 1], label='cyy')

    # plt.plot(cr1 / 100.0)
    # plt.figure()
    # plt.plot(range(K), a[:, 1, 1, 0, 0], label='axx')
    # plt.plot(range(K), a[:, 0, 1], label='axy')
    # plt.plot(range(K), b[:, 1, 1, 0, 0], label='bxx')
    # plt.plot(range(K), b[:, 0, 1], label='bxy')
    # plt.plot(range(K), qq[:, 0, 0], label='other')
    # plt.plot(grad2x * n2x + grad2y ** 2)
    # plt.legend()

    # plt.figure()
    # plt.plot(a[:, 0, 0] / (1.0 * b[:, 0, 0]))
    # plt.plot(a[:, 1, 1] / (1.0 * b[:, 1, 1]))
    # plt.plot(a[:, 0, 1] / (1.0 * b[:, 0, 1]))
    # plt.ylim([-1.5, 1.5])
    # # plt.plot(grad2x, label='gradx')
    # # plt.plot(grad2y, label='grady')
    # # plt.plot(n2y, label='normal')

    # plt.figure()
    # # plt.plot(k_rh_val[:, 0, 0], label='regularized')
    # # plt.plot(k_h_val[:, 0, 0], label='hyp')
    # plt.plot(k_h_val[:, 0, 0] / k_rh_val[:, 0, 0], label='divided')
    # plt.legend()

    # plt.figure()
    # plt.plot(n2y, label='normal')
    # plt.plot(cr2, label='cr')
    # plt.legend()
    # plt.show()
    np.testing.assert_almost_equal(a, b, 2)
    np.testing.assert_almost_equal(a, c, 2)
    np.testing.assert_almost_equal(b, c, 2)
Beispiel #8
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]
Beispiel #9
0
 def time_dbl_integral():
     for i in range(10000):
         a = fp.double_integral(msh.elements[0].mapping.eval,
                            msh.elements[4].mapping.eval,
                            k_d, bf, bf, o_q, i_q,
                            0, 0)