Exemplo n.º 1
0
def ellipse(locs, mesh, scale=1.0, rotation=None):
    r"""
    Ellipse indicator function associated with a list of region of interest tuples.

    Takes the value `scale` in the region

  ..math::
        (x - x_0)^2/r_x^2 + (y - y_0)^2/r_y^2 < 1

    and zero elsewhere. Similarly for other dimensions.

    :kwarg scale: scale factor for indicator.
    :kwarg rotation: angle by which to rotate.
    """
    d = mesh.topological_dimension()
    dims, L = range(d), range(len(locs))  # Itersets
    x = SpatialCoordinate(mesh)

    # Get distances from origins and RHS values
    X = [[x[i] - locs[j][i] for i in dims] for j in L]
    r = [[
        locs[j][d] if len(locs[j]) == d + 1 else locs[j][d + i] for i in dims
    ] for j in L]

    # Apply rotations
    if rotation is not None:
        rotate(X, rotation)

    # Combine to get indicator
    conditions = [lt(sum((X[j][i] / r[j][i])**2 for i in dims), 1) for j in L]
    return conditional(combine(Or, *conditions), scale, 0)
Exemplo n.º 2
0
def box(locs, mesh, scale=1.0, rotation=None):
    r"""
    Rectangular indicator functions associated with a list of region of interest tuples.

    Takes the value `scale` in the region

  ..math::
        (|x - x0| < r_x) && (|y - y0| < r_y)

    centred about (x0, y0) and zero elsewhere. Similarly for other dimensions.

    :kwarg scale: scale factor for indicator.
    :kwarg rotation: angle by which to rotate.
    """
    d = mesh.topological_dimension()
    dims, L = range(d), range(len(locs))  # Itersets
    x = SpatialCoordinate(mesh)

    # Get distances from origins and RHS values
    X = [[x[i] - locs[j][i] for i in dims] for j in L]
    r = [[
        locs[j][d] if len(locs[j]) == d + 1 else locs[j][d + i] for i in dims
    ] for j in L]

    # Apply rotations
    if rotation is not None:
        rotate(X, rotation)

    # Combine to get indicator
    expr = [
        combine(And, *[lt(abs(X[j][i]), r[j][i]) for i in dims]) for j in L
    ]
    return conditional(combine(Or, *expr), scale, 0.0)
Exemplo n.º 3
0
def gaussian(locs, mesh, scale=1.0, rotation=None):
    r"""
    Gaussian bell associated with a list of region of interest tuples.

    Takes the form

  ..math::
        \exp\left(- \left(\frac{x^2}{r_x^2} + \frac{y^2}{r_y^2}\right)\right)

    scaled by `scale` inside the ball region. Similarly for other dimensions.

    :kwarg scale: scale factor for indicator.
    :kwarg rotation: angle by which to rotate.
    """
    d = mesh.topological_dimension()
    dims, L = range(d), range(len(locs))  # Itersets
    x = SpatialCoordinate(mesh)

    # Get distances from origins and RHS values
    X = [[x[i] - locs[j][i] for i in dims] for j in L]
    r = [[
        locs[j][d] if len(locs[j]) == d + 1 else locs[j][d + i] for i in dims
    ] for j in L]

    # Apply rotations
    if rotation is not None:
        rotate(X, rotation)

    # Combine to get indicator
    q_sq = [sum((X[j][i] / r[j][i])**2 for i in dims)
            for j in L]  # Quotient of squares
    # return sum(scale*conditional(lt(q_sq[j], 1), exp(-q_sq[j]), 0) for j in L)
    return sum(scale * exp(-q_sq[j]) for j in L)
Exemplo n.º 4
0
def bump(locs, mesh, scale=1.0, rotation=None):
    r"""
    Rectangular bump function associated with a list of region of interest tuples.
    (A smooth approximation to the box function.)

    Takes the form

  ..math::
        \exp\left(1 - \frac1{\left(1 - \left(\frac{x - x_0}{r_x}\right)^2\right)}\right)
        * \exp\left(1 - \frac1{\left(1 - \left(\frac{y - y_0}{r_y}\right)^2\right)}\right)

    scaled by `scale` inside the box region. Similarly for other dimensions.

    Note that we assume the provided regions are disjoint for this indicator.

    :kwarg scale: scale factor for indicator.
    :kwarg rotation: angle by which to rotate.
    """
    d = mesh.topological_dimension()
    dims, L = range(d), range(len(locs))  # Itersets
    x = SpatialCoordinate(mesh)

    # Get distances from origins and RHS values
    X = [[x[i] - locs[j][i] for i in dims] for j in L]
    r = [[
        locs[j][d] if len(locs[j]) == d + 1 else locs[j][d + i] for i in dims
    ] for j in L]

    # Apply rotations
    if rotation is not None:
        rotate(X, rotation)

    # Combine to get indicator
    q = [[(X[j][i] / r[j][i])**2 for i in dims]
         for j in L]  # Quotients of squared distances
    conditions = [combine(And, *[lt(q[j][i], 1) for i in dims]) for j in L]
    bumps = [prod([exp(1 - 1 / (1 - q[j][i])) for i in dims]) for j in L]
    return sum([conditional(conditions[j], scale * bumps[j], 0) for j in L])
Exemplo n.º 5
0
def circular_bump(locs, mesh, scale=1.0, rotation=None):
    r"""
    Circular bump function associated with a list of region of interest tuples.
    (A smooth approximation to the ball function.)

    Defining the radius :math:`r^2 := (x - x_0)^2 + (y - y_0)^2`, the circular bump takes the
    form

  ..math::
        \exp\left(1 - \frac1{\left1 - \frac{r^2}{r_0^2}\right)}\right)

    scaled by `scale` inside the ball region. Similarly for other dimensions.

    :kwarg scale: scale factor for indicator.
    :kwarg rotation: angle by which to rotate.
    """
    d = mesh.topological_dimension()
    dims, L = range(d), range(len(locs))  # Itersets
    x = SpatialCoordinate(mesh)

    # Get distances from origins and RHS values
    X = [[x[i] - locs[j][i] for i in dims] for j in L]
    r_sq = [[
        locs[j][d]**2 if len(locs[j]) == d + 1 else locs[j][d + i]**2
        for i in dims
    ] for j in L]

    # Apply rotations
    if rotation is not None:
        rotate(X, rotation)

    # Combine to get indicator
    q = [sum([X[j][i]**2 for i in dims]) / sum(r_sq[j])
         for j in L]  # Quotient of squared 2-norms
    return sum([
        conditional(lt(q[j], 1), scale * exp(1 - 1 / (1 - q[j])), 0) for j in L
    ])