예제 #1
0
def rot90_director(data, axis="+x", out=None):
    """
    Rotate a director field by 90 degrees around the specified axis.
    
    Parameters
    ----------
    data: array_like
        Array specifying director field with ndim = 4.
    axis: str
        Axis around which to perform rotation. Can be in the form of
        '[s][n]X' where the optional parameter 's' can be "+" or "-" decribing 
        the sign of rotation. [n] is an integer describing number of rotations 
        to perform, and 'X' is one of 'x', 'y' 'z', and defines rotation axis.
    out : ndarray, optional
        Output array.
    
    Returns
    -------
    y : ndarray
        A rotated director field
        
    See Also
    --------   
    data.rotate_director : a general rotation for arbitrary angle.        
    """
    nz, ny, nx, nv = data.shape

    axis_name = axis[-1]
    try:
        k = int(axis[:-1])
    except ValueError:
        k = int(axis[:-1] + "1")
    angle = np.pi / 2 * k
    if axis_name == "x":
        r = rotation_matrix_x(angle)
        axes = (1, 0)
    elif axis_name == "y":
        r = rotation_matrix_y(angle)
        axes = (0, 2)
    elif axis_name == "z":
        r = rotation_matrix_z(angle)
        axes = (2, 1)
    else:
        raise ValueError("Unknown axis type {}".format(axis_name))
    data_rot = np.rot90(data, k=k, axes=axes)  #first rotate data points
    return rotate_vector(r, data_rot, out)  #rotate vector in each voxel
예제 #2
0
def rotate_director(rmat,
                    data,
                    method="linear",
                    fill_value=(0., 0., 0.),
                    norm=True,
                    out=None):
    """
    Rotate a director field around the center of the compute box by a specified
    rotation matrix. This rotation is lossy, as datapoints are interpolated.
    The shape of the output remains the same.
    
    Parameters
    ----------
    rmat : array_like
        A 3x3 rotation matrix.
    data: array_like
        Array specifying director field with ndim = 4
    method : str
        Interpolation method "linear" or "nearest"
    fill_value : numbers, optional
        If provided, the values (length 3 vector) to use for points outside of the
        interpolation domain. Defaults to (0.,0.,0.).
    norm : bool,
        Whether to normalize the length of the director to 1. after rotation 
        (interpolation) is performed. Because of interpolation error, the length 
        of the director changes slightly, and this options adds a constant 
        length constraint to reduce the error.
    out : ndarray, optional
        Output array.
        
    Returns
    -------
    y : ndarray
        A rotated director field
        
    See Also
    --------   
    data.rot90_director : a lossless rotation by 90 degrees.
        
    """

    from scipy.interpolate import RegularGridInterpolator
    verbose_level = DTMMConfig.verbose
    if verbose_level > 0:
        print("Rotating director.")

    out = np.empty_like(data)
    nz, ny, nx, nv = data.shape
    shape = (nz, ny, nx)
    az, ay, ax = [np.arange(-l / 2. + .5, l / 2. + .5) for l in shape]

    fillx, filly, fillz = fill_value
    xdir = RegularGridInterpolator((az, ay, ax),
                                   data[..., 0],
                                   fill_value=fillx,
                                   bounds_error=False,
                                   method=method)
    ydir = RegularGridInterpolator((az, ay, ax),
                                   data[..., 1],
                                   fill_value=filly,
                                   bounds_error=False,
                                   method=method)
    zdir = RegularGridInterpolator((az, ay, ax),
                                   data[..., 2],
                                   fill_value=fillz,
                                   bounds_error=False,
                                   method=method)
    zz, yy, xx = np.meshgrid(az,
                             ay,
                             ax,
                             indexing="ij",
                             copy=False,
                             sparse=True)

    out[..., 0] = xx
    out[..., 1] = yy
    out[..., 2] = zz
    out = rotate_vector(rmat.T, out, out)  #rotate coordinates

    #out2 = out.copy()
    #out2[...,0] = out[...,2]
    #out2[...,2] = out[...,0]

    out2 = out[..., ::-1]  #reverse direction instead of copying

    #interpolate new director field
    xnew = xdir(out2)
    ynew = ydir(out2)
    znew = zdir(out2)

    out[..., 0] = xnew
    out[..., 1] = ynew
    out[..., 2] = znew

    rotate_vector(rmat, out, out)  #rotate vector in each voxel

    if norm == True:
        s = director2order(out)
        mask = (s == 0.)
        s[mask] = 1.
        return np.divide(out, s[..., None], out)
    return
예제 #3
0
size_x = pitch_x * 1
size_z = pitch_z * 2

tilt = np.arctan(pitch_z / pitch_x)

twist = np.arange(
    0, 2 * np.pi * size_z / pitch_z, 2 * np.pi / pitch_z)[:, None] + np.arange(
        0, 2 * np.pi * size_x / pitch_x, 2 * np.pi / pitch_x)[None, :]

director = np.empty(shape=twist.shape + (3, ))
director[..., 0] = np.cos(twist)  #x component
director[..., 1] = np.sin(twist)  #y component
director[..., 2] = 0  # z component

r = rotation.rotation_matrix_y(tilt)
director = rotation.rotate_vector(r, director)
epsa = data.director2angles(director)

#: box dimensions
NLAYERS, HEIGHT, WIDTH = twist.shape[0], twist.shape[1], 1

d = np.ones(shape=(NLAYERS, ))

epsv = np.empty(shape=(NLAYERS, HEIGHT, 3), dtype=dtmm.conf.CDTYPE)

epsv[..., 0] = no**2
epsv[..., 1] = no**2
epsv[..., 2] = ne**2

beta, phi, intensity = 0, 0, 1