Esempio n. 1
0
def warp_and_blend_nodes_2d(n, node_tuples=None):
    try:
        alpha = _alpha_opt_2d[n-1]
    except IndexError:
        alpha = 5/3

    if node_tuples is None:
        from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \
                as gnitstam
        node_tuples = list(gnitstam(n, 2))
    else:
        if len(node_tuples) != (n+1)*(n+2)//2:
            raise ValueError("node_tuples list does not have the correct length")

    # shape: (2, nnodes)
    unit_nodes = (np.array(node_tuples, dtype=np.float64)/n*2 - 1).T

    from modepy.tools import (
            unit_to_barycentric,
            barycentric_to_equilateral,
            equilateral_to_unit)
    bary = unit_to_barycentric(unit_nodes)

    return equilateral_to_unit(
        barycentric_to_equilateral(bary)
        + _2d_equilateral_shift(n, bary, alpha))
Esempio n. 2
0
def test_barycentric_coordinate_map(dims):
    from random import Random
    rng = Random(17)

    n = 5
    unit = np.empty((dims, n))
    from modepy.tools import (
            pick_random_simplex_unit_coordinate,
            unit_to_barycentric,
            barycentric_to_unit,
            barycentric_to_equilateral,
            equilateral_to_unit,)

    for i in range(n):
        unit[:, i] = pick_random_simplex_unit_coordinate(rng, dims)

    bary = unit_to_barycentric(unit)
    assert (np.abs(np.sum(bary, axis=0) - 1) < 1e-15).all()
    assert (bary >= 0).all()
    unit2 = barycentric_to_unit(bary)
    assert la.norm(unit-unit2) < 1e-14

    equi = barycentric_to_equilateral(bary)
    unit3 = equilateral_to_unit(equi)
    assert la.norm(unit-unit3) < 1e-14
Esempio n. 3
0
def test_barycentric_coordinate_map(dims):
    from random import Random
    rng = Random(17)

    n = 5
    unit = np.empty((dims, n))
    from modepy.tools import (
        pick_random_simplex_unit_coordinate,
        unit_to_barycentric,
        barycentric_to_unit,
        barycentric_to_equilateral,
        equilateral_to_unit,
    )

    for i in range(n):
        unit[:, i] = pick_random_simplex_unit_coordinate(rng, dims)

    bary = unit_to_barycentric(unit)
    assert (np.abs(np.sum(bary, axis=0) - 1) < 1e-15).all()
    assert (bary >= 0).all()
    unit2 = barycentric_to_unit(bary)
    assert la.norm(unit - unit2) < 1e-14

    equi = barycentric_to_equilateral(bary)
    unit3 = equilateral_to_unit(equi)
    assert la.norm(unit - unit3) < 1e-14
Esempio n. 4
0
def test_barycentric_coordinate_map(dims):
    n = 100
    from modepy.tools import (
        unit_to_barycentric,
        barycentric_to_unit,
        barycentric_to_equilateral,
        equilateral_to_unit,
    )

    rng = np.random.Generator(np.random.PCG64(17))
    unit = nd.random_nodes_for_shape(shp.Simplex(dims), n, rng=rng)

    bary = unit_to_barycentric(unit)
    assert (np.abs(np.sum(bary, axis=0) - 1) < 1e-15).all()
    assert (bary >= 0).all()
    unit2 = barycentric_to_unit(bary)
    assert la.norm(unit - unit2) < 1e-14

    equi = barycentric_to_equilateral(bary)
    unit3 = equilateral_to_unit(equi)
    assert la.norm(unit - unit3) < 1e-14
Esempio n. 5
0
def warp_and_blend_nodes_2d(n, node_tuples=None):
    try:
        alpha = _alpha_opt_2d[n - 1]
    except IndexError:
        alpha = 5 / 3

    space = PN(2, n)
    if node_tuples is None:
        node_tuples = node_tuples_for_space(space)
    else:
        if len(node_tuples) != space.space_dim:
            raise ValueError(
                "'node_tuples' list does not have the correct length")

    # shape: (2, nnodes)
    unit_nodes = (np.array(node_tuples, dtype=np.float64) / n * 2 - 1).T

    from modepy.tools import (unit_to_barycentric, barycentric_to_equilateral,
                              equilateral_to_unit)
    bary = unit_to_barycentric(unit_nodes)

    return equilateral_to_unit(
        barycentric_to_equilateral(bary) +
        _2d_equilateral_shift(n, bary, alpha))
Esempio n. 6
0
def warp_and_blend_nodes_3d(n, node_tuples=None):
    try:
        alpha = _alpha_opt_3d[n-1]
    except IndexError:
        alpha = 1.

    if node_tuples is None:
        from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \
                as gnitstam
        node_tuples = list(gnitstam(n, 3))
    else:
        if len(node_tuples) != (n+1)*(n+2)*(n+3)//6:
            raise ValueError("node_tuples list does not have the correct length")

    # shape: (3, nnodes)
    unit_nodes = (np.array(node_tuples, dtype=np.float64)/n*2 - 1).T

    from modepy.tools import (
            unit_to_barycentric,
            barycentric_to_equilateral,
            equilateral_to_unit,
            EQUILATERAL_VERTICES)
    bary = unit_to_barycentric(unit_nodes)
    equi = barycentric_to_equilateral(bary)

    equi_vertices = EQUILATERAL_VERTICES[3]

    # total number of nodes and tolerance
    tol = 1e-8

    shift = np.zeros_like(equi)

    for i1, i2, i3, i4, vertex_step in [
            (0, 1, 2, 3, -1),
            (1, 2, 3, 0, -1),
            (2, 3, 0, 1, -1),
            (3, 0, 1, 2, -1),
            ]:

        vi2, vi3, vi4 = [(i1 + vertex_step*i) % 4 for i in range(1, 4)]

        # all vertices have the same distance from the origin
        tangent1 = equi_vertices[vi3] - equi_vertices[vi4]
        tangent1 /= la.norm(tangent1)

        tangent2 = equi_vertices[vi2] - equi_vertices[vi3]
        tangent2 -= np.dot(tangent1, tangent2)*tangent1

        tangent2 /= la.norm(tangent2)

        sub_bary = bary[[i2, i3, i4]]
        warp1, warp2 = _2d_equilateral_shift(n, sub_bary, alpha)

        l1 = bary[i1]
        l2, l3, l4 = sub_bary

        blend = l2*l3*l4

        denom = (l2+0.5*l1)*(l3+0.5*l1)*(l4+0.5*l1)
        denom_ok = denom > tol

        blend[denom_ok] = (
                (1+(alpha*l1[denom_ok])**2)
                * blend[denom_ok]
                / denom[denom_ok])

        shift = shift + (blend*warp1)[np.newaxis, :] * tangent1[:, np.newaxis]
        shift = shift + (blend*warp2)[np.newaxis, :] * tangent2[:, np.newaxis]

        is_face = (l1 < tol) & ((l2 > tol) | (l3 > tol) | (l4 > tol))

        # assign face warp separately
        shift[:, is_face] = (
                + warp1[is_face][np.newaxis, :] * tangent1[:, np.newaxis]
                + warp2[is_face][np.newaxis, :] * tangent2[:, np.newaxis]
                )

    return equilateral_to_unit(equi + shift)
Esempio n. 7
0
File: nodes.py Progetto: userjjb/DbX
def warp_and_blend_nodes_3d(n, node_tuples=None):
    try:
        alpha = _alpha_opt_3d[n - 1]
    except IndexError:
        alpha = 1.

    if node_tuples is None:
        from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \
                as gnitstam
        node_tuples = list(gnitstam(n, 3))
    else:
        if len(node_tuples) != (n + 1) * (n + 2) * (n + 3) // 6:
            raise ValueError(
                "node_tuples list does not have the correct length")

    # shape: (3, nnodes)
    unit_nodes = (np.array(node_tuples, dtype=np.float64) / n * 2 - 1).T

    from modepy.tools import (unit_to_barycentric, barycentric_to_equilateral,
                              equilateral_to_unit, EQUILATERAL_VERTICES)
    bary = unit_to_barycentric(unit_nodes)
    equi = barycentric_to_equilateral(bary)

    equi_vertices = EQUILATERAL_VERTICES[3]

    # total number of nodes and tolerance
    tol = 1e-8

    shift = np.zeros_like(equi)

    for i1, i2, i3, i4, vertex_step in [
        (0, 1, 2, 3, -1),
        (1, 2, 3, 0, -1),
        (2, 3, 0, 1, -1),
        (3, 0, 1, 2, -1),
    ]:

        vi2, vi3, vi4 = [(i1 + vertex_step * i) % 4 for i in range(1, 4)]

        # all vertices have the same distance from the origin
        tangent1 = equi_vertices[vi3] - equi_vertices[vi4]
        tangent1 /= la.norm(tangent1)

        tangent2 = equi_vertices[vi2] - equi_vertices[vi3]
        tangent2 -= np.dot(tangent1, tangent2) * tangent1

        tangent2 /= la.norm(tangent2)

        sub_bary = bary[[i2, i3, i4]]
        warp1, warp2 = _2d_equilateral_shift(n, sub_bary, alpha)

        l1 = bary[i1]
        l2, l3, l4 = sub_bary

        blend = l2 * l3 * l4

        denom = (l2 + 0.5 * l1) * (l3 + 0.5 * l1) * (l4 + 0.5 * l1)
        denom_ok = denom > tol

        blend[denom_ok] = ((1 + (alpha * l1[denom_ok])**2) * blend[denom_ok] /
                           denom[denom_ok])

        shift = shift + (blend * warp1)[np.newaxis, :] * tangent1[:,
                                                                  np.newaxis]
        shift = shift + (blend * warp2)[np.newaxis, :] * tangent2[:,
                                                                  np.newaxis]

        is_face = (l1 < tol) & ((l2 > tol) | (l3 > tol) | (l4 > tol))

        # assign face warp separately
        shift[:, is_face] = (
            +warp1[is_face][np.newaxis, :] * tangent1[:, np.newaxis] +
            warp2[is_face][np.newaxis, :] * tangent2[:, np.newaxis])

    return equilateral_to_unit(equi + shift)