Пример #1
0
 def _compute_ft(self):
     self.S = np.zeros((len(self.K),), dtype=np.complex128)
     for i, k in enumerate(self.K):
         for r, q in zip(self.position, self.orientation):
             k_sq = np.dot(k, k)
             """
             The FT of an object with orientation q at a given k-space point
             is the same as the FT of the unrotated object at a k-space
             point rotated the opposite way. The opposite of the rotation
             represented by a quaternion is the conjugate of the quaternion,
             found by inverting the sign of the imaginary components.
             """
             k = rowan.rotate(rowan.inverse(q), k)
             f = 0
             if k_sq == 0:
                 f = self.volume
             else:
                 for face_id, face in enumerate(self.faces):
                     norm = self.norms[face_id]
                     k_dot_norm = np.dot(norm, k)
                     k_projected = k - k_dot_norm * norm
                     k_projected_sq = np.dot(k_projected, k_projected)
                     f2d = 0
                     if k_projected_sq == 0:
                         f2d = self.areas[face_id]
                     else:
                         n_verts = len(face)
                         for edge_id in range(n_verts):
                             r0 = self.verts[face[edge_id]]
                             r1 = self.verts[face[(edge_id + 1) % n_verts]]
                             edge_vec = r1 - r0
                             edge_center = 0.5 * (r0 + r1)
                             edge_cross_k = np.cross(edge_vec, k_projected)
                             k_dot_center = np.dot(k_projected, edge_center)
                             k_dot_edge = np.dot(k_projected, edge_vec)
                             # Note that np.sinc(x) gives sin(pi*x)/(pi*x)
                             f_n = (
                                 np.dot(norm, edge_cross_k)
                                 * np.sinc(0.5 * k_dot_edge / np.pi)
                                 / k_projected_sq
                             )
                             f2d -= f_n * 1j * np.exp(-1j * k_dot_center)
                     d = self.d[face_id]
                     exp_kr = np.exp(-1j * k_dot_norm * d)
                     f += k_dot_norm * (1j * f2d * exp_kr)
                 # end loop over faces
                 f /= k_sq
             # end if/else, f is now calculated
             # S += rho * f * exp(-i k r)
             self.S[i] += (
                 self.density
                 * f
                 * np.exp(-1j * np.dot(k, rowan.rotate(rowan.inverse(q), r)))
             )
Пример #2
0
 def test_inverse(self):
     """Test quaternion inverse."""
     np.random.seed(0)
     shapes = [(4,), (5, 4), (5, 5, 4), (5, 5, 5, 4)]
     for shape in shapes:
         quats = np.random.random_sample(shape)
         quats_conj = quats.copy()
         quats_conj[..., 1:] *= -1
         quats_conj /= rowan.norm(quats)[..., np.newaxis] ** 2
         self.assertTrue(np.allclose(rowan.inverse(quats), quats_conj))
Пример #3
0
 def test_divide(self):
     """Ensure division works"""
     shapes = [(4, ), (5, 4), (5, 5, 4), (5, 5, 5, 4)]
     np.random.seed(0)
     for shape_i in shapes:
         x = np.random.random_sample(shape_i)
         for shape_j in shapes:
             y = np.random.random_sample(shape_j)
             self.assertTrue(
                 np.allclose(rowan.divide(x, y),
                             rowan.multiply(x, rowan.inverse(y))))
Пример #4
0
def to_view(bod, view_orientation, image_size):
    lin_grid = np.linspace(-1, 1, image_size)
    x, y = np.meshgrid(lin_grid, lin_grid)
    y = -y
    r2 = x**2 + y**2
    z = np.sqrt(np.clip(1 - r2, 0, None))
    xyz = np.dstack((x, y, z))
    xyz = rowan.rotate(rowan.inverse(view_orientation), xyz)
    x, y, z = xyz[:, :, 0], xyz[:, :, 1], xyz[:, :, 2]
    view = np.zeros((image_size, image_size))
    phi = np.arccos(z)
    theta = np.arctan2(y, x) % (2 * np.pi)
    num_theta_bins, num_phi_bins = bod.nbins
    theta_bin_edges, phi_bin_edges = bod.bin_edges
    theta_bins = np.trunc(theta / (2 * np.pi) * num_theta_bins).astype(int)
    phi_bins = np.trunc(phi / np.pi * num_phi_bins).astype(int)
    view = bod.bond_order[theta_bins, phi_bins]
    view[r2 > 1] = np.nan
    return view
Пример #5
0
    def read(self):
        "Read the frame data from the stream."
        self.stream.seek(self.start)
        i = line = None

        def _assert(assertion):
            assert i is not None
            assert line is not None
            if not assertion:
                raise ParserError("Failed to read line #{}: {}.".format(
                    i, line))

        monotype = False
        raw_frame = _RawFrameData()
        raw_frame.view_rotation = None
        for i, line in enumerate(self.stream):
            if _is_comment(line):
                continue
            if line.startswith('#'):
                if line.startswith('#[data]'):
                    _assert(raw_frame.data is None)
                    raw_frame.data_keys, raw_frame.data, j = \
                        self._read_data_section(line, self.stream)
                    i += j
                else:
                    raise ParserError(line)
            else:
                tokens = line.rstrip().split()
                if not tokens:
                    continue  # empty line
                elif tokens[0] in TOKENS_SKIP:
                    continue  # skip these lines
                if tokens[0] == 'eof':
                    logger.debug("Reached end of frame.")
                    break
                elif tokens[0] == 'def':
                    definition, data, end = line.strip().split('"')
                    _assert(len(end) == 0)
                    name = definition.split()[1]
                    type_shape = self._parse_shape_definition(data)
                    if name not in raw_frame.types:
                        raw_frame.types.append(name)
                        raw_frame.type_shapes.append(type_shape)
                    else:
                        typeid = raw_frame.type_shapes.index(name)
                        raw_frame.type_shapes[typeid] = type_shape
                        warnings.warn(
                            "Redefinition of type '{}'.".format(name))
                elif tokens[0] == 'shape':  # monotype
                    data = line.strip().split('"')[1]
                    raw_frame.types.append(self.default_type)
                    type_shape = self._parse_shape_definition(data)
                    raw_frame.type_shapes.append(type_shape)
                    _assert(len(raw_frame.type_shapes) == 1)
                    monotype = True
                elif tokens[0] in ('boxMatrix', 'box'):
                    if len(tokens) == 10:
                        raw_frame.box = np.array(
                            [self._num(v) for v in tokens[1:]]).reshape((3, 3))
                    elif len(tokens) == 4:
                        raw_frame.box = np.array([[self._num(tokens[1]), 0, 0],
                                                  [0,
                                                   self._num(tokens[2]), 0],
                                                  [0, 0,
                                                   self._num(tokens[3])]
                                                  ]).reshape((3, 3))
                elif tokens[0] == 'rotation':
                    euler_angles = np.array([float(t) for t in tokens[1:]])
                    euler_angles *= np.pi / 180
                    raw_frame.view_rotation = rowan.from_euler(
                        *euler_angles, axis_type='extrinsic', convention='xyz')
                else:
                    # assume we are reading positions now
                    if not monotype:
                        name = tokens[0]
                        if name not in raw_frame.types:
                            raw_frame.types.append(name)
                            type_shape = self._parse_shape_definition(' '.join(
                                tokens[:3]))
                            raw_frame.type_shapes.append(type_shape)
                    else:
                        name = self.default_type
                    typeid = raw_frame.types.index(name)
                    type_shape = raw_frame.type_shapes[typeid]
                    if len(tokens) == 7 and isinstance(type_shape, ArrowShape):
                        xyz = tokens[-6:-3]
                        quat = tokens[-3:] + [0]
                    elif len(tokens) >= 7:
                        xyz = tokens[-7:-4]
                        quat = tokens[-4:]
                    elif len(tokens) >= 3:
                        xyz = tokens[-3:]
                        quat = None
                    else:
                        raise ParserError(line)
                    raw_frame.typeid.append(typeid)
                    raw_frame.position.append([self._num(v) for v in xyz])
                    if quat is None:
                        raw_frame.orientation.append(quat)
                    else:
                        raw_frame.orientation.append(
                            [self._num(v) for v in quat])

        # Perform inverse rotation to recover original coordinates
        if raw_frame.view_rotation is not None:
            pos = rowan.rotate(rowan.inverse(raw_frame.view_rotation),
                               raw_frame.position)
        else:
            pos = np.asarray(raw_frame.position)
        # If all the z coordinates are close to zero, set box dimension to 2
        if np.allclose(pos[:, 2], 0.0, atol=1e-7):
            raw_frame.box_dimensions = 2

        # If no valid orientations have been added, the array should be empty
        if all([quat is None for quat in raw_frame.orientation]):
            raw_frame.orientation = []
        else:
            # Replace values of None with an identity quaternion
            for i in range(len(raw_frame.orientation)):
                if raw_frame.orientation[i] is None:
                    raw_frame.orientation[i] = [1, 0, 0, 0]
        return raw_frame
    def f(self, X, Z, A, t, logentry=None):
        # x = X[0]
        # y = X[1]
        # z = X[2]
        # xdot = X[3]
        # ydot = X[4]
        # zdot = X[5]
        # qw = X[6]
        # qx = X[7]
        # qy = X[8]
        # qz = X[9]
        # wx = X[10]
        # wy = X[11]
        # wz = X[12]
        a = Z**2
        # a = A
        J = self.J
        dxdt = np.zeros(13)
        q = X[6:10]
        q = rowan.normalize(q)
        omega = X[10:]
        B0 = self.B0 * self.params['C_T']
        # B0 = self.B0
        eta = np.dot(B0, a)
        f_u = np.array([0, 0, eta[0]])
        tau_u = np.array([eta[1], eta[2], eta[3]])

        dxdt[0:3] = X[3:6]
        # dxdt[3:6] = -9.81 + rowan.rotate(q, f_u) / self.params['m']
        dxdt[3:6] = np.array([0., 0., -9.81
                              ]) + rowan.rotate(q, f_u) / self.params['m']
        Vinf = self.params['Vwind_mean'] - np.linalg.norm(X[3:6])
        Vinf_B = rowan.rotate(rowan.inverse(q), Vinf)
        Vz_B = np.array([0.0, 0.0, Vinf_B[2]])
        Vs_B = Vinf_B - Vz_B
        alpha = np.arcsin(np.linalg.norm(Vz_B) / np.linalg.norm(Vinf_B))
        n = np.sqrt(
            np.multiply(a, self.B0[0, :]) /
            (self.params['C_T'] * self.params['rho'] * self.params['D']**4))
        Fs_B = (Vs_B / np.linalg.norm(Vs_B)
                ) * self.params['C_s'] * self.params['rho'] * sum(
                    n**self.params['k1']) * (np.linalg.norm(Vinf)**(
                        2 - self.params['k1'])) * (self.params['D']**(
                            2 + self.params['k1'])) * (
                                (np.pi / 2)**2 -
                                alpha**2) * (alpha + self.params['k2'])
        # Fs_B = [0,0,0]
        dxdt[3:6] += rowan.rotate(q, Fs_B) / self.mass
        qnew = rowan.calculus.integrate(q, omega, self.ave_dt)
        if qnew[0] < 0:
            qnew = -qnew

        dxdt[6:10] = (qnew - q) / self.ave_dt
        dxdt[10:] = 1 / J * (np.cross(J * omega, omega) + tau_u)
        dxdt[10:] += 1 / J * np.cross(
            np.array([0.0, 0.0, self.params['D'] / 4]), Fs_B)
        euler_o = rowan.to_euler(q, 'xyz')
        if logentry is not None:
            logentry['f_u'] = f_u
            logentry['tau'] = tau_u
            logentry['euler_o'] = euler_o

        return dxdt.reshape((len(dxdt), 1))