Пример #1
0
def is_affine_simplex_group(group, abs_tol=None):
    if abs_tol is None:
        abs_tol = 1.0e-13

    if not isinstance(group, SimplexElementGroup):
        raise TypeError("expected a 'SimplexElementGroup' not '%s'" %
                type(group).__name__)

    # get matrices
    basis = mp.simplex_best_available_basis(group.dim, group.order)
    grad_basis = mp.grad_simplex_best_available_basis(group.dim, group.order)

    vinv = la.inv(mp.vandermonde(basis, group.unit_nodes))
    diff = mp.differentiation_matrices(basis, grad_basis, group.unit_nodes)
    if not isinstance(diff, tuple):
        diff = (diff,)

    # construct all second derivative matrices (including cross terms)
    from itertools import product
    mats = []
    for n in product(range(group.dim), repeat=2):
        if n[0] > n[1]:
            continue
        mats.append(vinv.dot(diff[n[0]].dot(diff[n[1]])))

    # check just the first element for a non-affine local-to-global mapping
    ddx_coeffs = np.einsum("aij,bj->abi", mats, group.nodes[:, 0, :])
    norm_inf = np.max(np.abs(ddx_coeffs))
    if norm_inf > abs_tol:
        return False

    # check all elements for a non-affine local-to-global mapping
    ddx_coeffs = np.einsum("aij,bcj->abci", mats, group.nodes)
    norm_inf = np.max(np.abs(ddx_coeffs))
    return norm_inf < abs_tol
Пример #2
0
def test_diff_matrix(dims, eltype):
    n = 5

    if eltype == "simplex":
        nodes = mp.warp_and_blend_nodes(dims, n)
        basis = mp.simplex_onb(dims, n)
        grad_basis = mp.grad_simplex_onb(dims, n)
    elif eltype == "tensor":
        nodes = mp.legendre_gauss_lobatto_tensor_product_nodes(dims, n)
        basis = mp.legendre_tensor_product_basis(dims, n)
        grad_basis = mp.grad_legendre_tensor_product_basis(dims, n)
    else:
        raise ValueError(f"unknown element type: {eltype}")

    diff_mat = mp.differentiation_matrices(basis, grad_basis, nodes)
    if isinstance(diff_mat, tuple):
        diff_mat = diff_mat[0]

    f = np.sin(nodes[0])

    df_dx = np.cos(nodes[0])
    df_dx_num = np.dot(diff_mat, f)

    error = la.norm(df_dx - df_dx_num) / la.norm(df_dx)
    logger.info("error: %.5e", error)
    assert error < 2.0e-4, error
Пример #3
0
    def diff_matrices(self):
        result = mp.differentiation_matrices(
                self.basis(),
                mp.grad_simplex_onb(self.dim, self.order),
                self.unit_nodes)

        if not isinstance(result, tuple):
            return (result,)
        else:
            return result
Пример #4
0
    def diff_matrices(self):
        result = mp.differentiation_matrices(
                self.basis(),
                self.grad_basis(),
                self.unit_nodes)

        if not isinstance(result, tuple):
            return (result,)
        else:
            return result
Пример #5
0
def test_diff_matrix(dims):
    n = 5
    nodes = mp.warp_and_blend_nodes(dims, n)

    f = np.sin(nodes[0])
    df_dx = np.cos(nodes[0])

    diff_mat = mp.differentiation_matrices(mp.simplex_onb(dims, n),
                                           mp.grad_simplex_onb(dims, n), nodes)
    if isinstance(diff_mat, tuple):
        diff_mat = diff_mat[0]
    df_dx_num = np.dot(diff_mat, f)

    print(la.norm(df_dx - df_dx_num))
    assert la.norm(df_dx - df_dx_num) < 1e-3
Пример #6
0
    def diff_matrices(self):
        if len(self.basis()) != self.unit_nodes.shape[1]:
            from meshmode.discretization import NoninterpolatoryElementGroupError
            raise NoninterpolatoryElementGroupError(
                "%s does not support interpolation because it is not "
                "unisolvent (its unit node count does not match its "
                "number of basis functions). Differentiation requires "
                "the ability to interpolate." % type(self).__name__)

        result = mp.differentiation_matrices(self.basis(), self.grad_basis(),
                                             self.unit_nodes)

        if not isinstance(result, tuple):
            return (result, )
        else:
            return result
Пример #7
0
def test_diff_matrix(dims):
    n = 5
    nodes = mp.warp_and_blend_nodes(dims, n)

    f = np.sin(nodes[0])
    df_dx = np.cos(nodes[0])

    diff_mat = mp.differentiation_matrices(
            mp.simplex_onb(dims, n),
            mp.grad_simplex_onb(dims, n),
            nodes)
    if isinstance(diff_mat, tuple):
        diff_mat = diff_mat[0]
    df_dx_num = np.dot(diff_mat, f)

    print((la.norm(df_dx-df_dx_num)))
    assert la.norm(df_dx-df_dx_num) < 1e-3
Пример #8
0
    def diff_matrices(self):
        if len(self.basis()) != self.unit_nodes.shape[1]:
            from meshmode.discretization import NoninterpolatoryElementGroupError
            raise NoninterpolatoryElementGroupError(
                    "%s does not support interpolation because it is not "
                    "unisolvent (its unit node count does not match its "
                    "number of basis functions). Differentiation requires "
                    "the ability to interpolate." % type(self).__name__)

        result = mp.differentiation_matrices(
                self.basis(),
                self.grad_basis(),
                self.unit_nodes)

        if not isinstance(result, tuple):
            return (result,)
        else:
            return result
Пример #9
0
def test_diff_matrix(dims, shape_cls, order=5):
    shape = shape_cls(dims)
    space = mp.space_for_shape(shape, order)
    nodes = mp.edge_clustered_nodes_for_space(space, shape)
    basis = mp.basis_for_space(space, shape)

    diff_mat = mp.differentiation_matrices(basis.functions, basis.gradients, nodes)
    if isinstance(diff_mat, tuple):
        diff_mat = diff_mat[0]

    f = np.sin(nodes[0])

    df_dx = np.cos(nodes[0])
    df_dx_num = np.dot(diff_mat, f)

    error = la.norm(df_dx - df_dx_num) / la.norm(df_dx)
    logger.info("error: %.5e", error)
    assert error < 2.0e-4, error
Пример #10
0
def test_diff_matrix_permutation(dims):
    order = 5

    from pytools import \
            generate_nonnegative_integer_tuples_summing_to_at_most as gnitstam
    node_tuples = list(gnitstam(order, dims))

    simplex_onb = mp.simplex_onb(dims, order)
    grad_simplex_onb = mp.grad_simplex_onb(dims, order)
    nodes = np.array(
        mp.warp_and_blend_nodes(dims, order, node_tuples=node_tuples))
    diff_matrices = mp.differentiation_matrices(simplex_onb, grad_simplex_onb,
                                                nodes)

    for iref_axis in range(dims):
        perm = mp.diff_matrix_permutation(node_tuples, iref_axis)

        assert la.norm(diff_matrices[iref_axis] -
                       diff_matrices[0][perm][:, perm]) < 1e-10
Пример #11
0
def diff_matrices(grp: InterpolatoryElementGroupBase) -> Tuple[np.ndarray]:
    if not isinstance(grp, InterpolatoryElementGroupBase):
        raise NoninterpolatoryElementGroupError(
            f"cannot construct diff matrices on '{type(grp).__name__}'")

    basis_fcts = grp.basis_obj().functions
    grad_basis_fcts = grp.basis_obj().gradients

    if len(basis_fcts) != grp.unit_nodes.shape[1]:
        raise NoninterpolatoryElementGroupError(
            f"{type(grp).__name__} does not support interpolation because "
            "it is not unisolvent (its unit node count does not match its "
            "number of basis functions). Differentiation requires "
            "the ability to interpolate.")

    result = mp.differentiation_matrices(basis_fcts, grad_basis_fcts,
                                         grp.unit_nodes)

    return result if isinstance(result, tuple) else (result, )
Пример #12
0
def test_diff_matrix_permutation(dims):
    order = 5
    space = mp.PN(dims, order)

    from pytools import \
            generate_nonnegative_integer_tuples_summing_to_at_most as gnitstam
    node_tuples = list(gnitstam(order, dims))

    simplex_onb = mp.orthonormal_basis_for_space(space, mp.Simplex(dims))
    nodes = np.array(mp.warp_and_blend_nodes(dims, order, node_tuples=node_tuples))
    diff_matrices = mp.differentiation_matrices(
            simplex_onb.functions, simplex_onb.gradients, nodes)

    for iref_axis in range(dims):
        perm = mp.diff_matrix_permutation(node_tuples, iref_axis)

        assert la.norm(
                diff_matrices[iref_axis]
                - diff_matrices[0][perm][:, perm]) < 1e-10