예제 #1
0
def test_unit_vector():
    """
    Test unit vector function
    """

    # Assert vector have length 1
    for v in [UNIT_X, SOME_VECTOR]:
        v = m.unit_vector(v)
        assert np.linalg.norm(v) == 1

    # Assert list/numpy arrays produce same output
    v_from_list = m.unit_vector(list(SOME_VECTOR))
    v_from_np = m.unit_vector(np.array(SOME_VECTOR))
    assert np.testing.assert_array_equal(v_from_list, v_from_np) is None
예제 #2
0
def _accel_vector(plot, ps):
    """
    Add a vector indicating the direction of (gravitational) acceleration

    Args:
        :plot: plot
        :ps: plot settings

    Returns:
        :plot: modified plot object
    """

    frame = ps['frame']

    accel_direction = frame.accel_direction
    accel_magnitude = np.linalg.norm(accel_direction)
    orig = 3 * GlobalSystem.UnitVectors.Z
    vector = unit_vector(accel_direction)

    plot.scatter(*orig, color=COLOR_BC, linewidth=ps['set_linewidth'])
    plot.quiver(*orig,
                *vector,
                length=1,
                color=COLOR_BC,
                linewidth=ps['set_vectorwidth'])
    plot.text(*orig,
              f"{accel_magnitude:.2e} m/s²",
              color=COLOR_BC,
              fontsize=ps['set_fontsize'])

    return plot
예제 #3
0
파일: _element.py 프로젝트: jphkun/framat
def get_local_system_from_up(x_elem, up):
    """
    Return the y- and z-axis of a Cartesian coordinate system (local element
    coordinate system) for a given x-axis and a defined "up-direction"

    Args:
        :x_elem: x-axis (of the element)
        :up: up-direction

    Returns:
        :y_axis: y-axis
        :z_axis: z-axis

    * Values are returned as a tuple
    """

    if abs(1 - abs(np.dot(x_elem, up))) <= 1e-10:
        logger.error("up-direction and local x-axis are parallel")
        raise ValueError("up-direction and local x-axis are parallel")

    z_elem = unit_vector(vector_rejection(up, x_elem))
    y_elem = unit_vector(np.cross(z_elem, x_elem))
    return (y_elem, z_elem)
예제 #4
0
파일: _element.py 프로젝트: jphkun/framat
    def __init__(self, p1, p2, up):
        """
        Beam finite element with 6 dof per node

        TODO
        """

        # ===== Geometry =====
        # Node points
        self.p1 = p1
        self.p2 = p2

        # Vectors of the local coordinate system
        self.x_elem = unit_vector(self.p2.coord - self.p1.coord)
        self.y_elem, self.z_elem = get_local_system_from_up(self.x_elem, up)

        # Additional geometric properties
        self.mid_point = (self.p1.coord + self.p2.coord) / 2
        self.mid_xsi = (self.p1.rel_coord + self.p2.rel_coord) / 2
        self.length = np.linalg.norm(self.p2.coord - self.p1.coord)

        # ===== Material and cross section properties =====
        self.properties = defaultdict(lambda: None)

        # ===== Load vector in the global system =====
        self.load_vector_glob = np.zeros((12, 1))
        self.mass_matrix_glob = np.zeros((12, 12))
        # self.stiffness_matrix_glob = np.zeros((12, 1))

        # ===== Transformation matrix =====
        lx = direction_cosine(self.x_elem, G.X)
        ly = direction_cosine(self.y_elem, G.X)
        lz = direction_cosine(self.z_elem, G.X)
        mx = direction_cosine(self.x_elem, G.Y)
        my = direction_cosine(self.y_elem, G.Y)
        mz = direction_cosine(self.z_elem, G.Y)
        nx = direction_cosine(self.x_elem, G.Z)
        ny = direction_cosine(self.y_elem, G.Z)
        nz = direction_cosine(self.z_elem, G.Z)

        T3 = np.array([[lx, mx, nx], [ly, my, ny], [lz, mz, nz]])
        self.T = np.zeros((12, 12))
        self.T[0:3, 0:3] = self.T[3:6, 3:6] = self.T[6:9,
                                                     6:9] = self.T[9:12,
                                                                   9:12] = T3
예제 #5
0
    def __init__(self, parent_beamline, xsi1, xsi2, uid1, uid2, up=None):
        """
        Beam finite element with 6 dof per node

        Args:
            :parent_beamline: parent beamline object
            :xsi1: relative position of first node
            :xsi2: relative position of second node
            :uid1: UID of node 1
            :uid2: UID of node 2
        """

        # Book keeping
        self.element_num = parent_beamline.parent_frame.counter.elements
        parent_beamline.parent_frame.finder.elements.update(
            self.element_num, self)
        parent_beamline.parent_frame.counter.increment_element_count()

        logger.debug(f"Adding new element no. '{self.element_num}'...")

        # Reference to parent beamline
        self.parent_beamline = parent_beamline

        # Element geometry
        node1_num = parent_beamline.parent_frame.counter.get_last_node_num(
        ) - 1
        node2_num = parent_beamline.parent_frame.counter.get_last_node_num()
        self.node1 = Node(self, uid1, xsi1, node1_num, elem_loc=1)
        self.node2 = Node(self, uid2, xsi2, node2_num, elem_loc=2)

        # Vectors of the local coordinate system
        self.x_elem = unit_vector(self.node2.coord - self.node1.coord)
        self.y_elem = None
        self.z_elem = None
        self.up = up

        # Element properties and loads
        self.properties = defaultdict(lambda: None)
        self.distributed_loads = defaultdict(int)
        self.concentrated_loads = defaultdict(int)
        self.point_properties = defaultdict(int)

        self.distributed_loads_in_loc_system = False
        self.concentrated_loads_in_loc_system = False
예제 #6
0
def add_freestream_vector(axes_2d,
                          axes_3d,
                          state,
                          tip_pos=np.array([0, 0, 0]),
                          vector_len=3):
    """
    Add a free stream vector

    Args:
        :axes_2d: 2D axes object (matplotlib)
        :axes_3d: 3D axes object (matplotlib)
        :state: State model
    """

    free_stream_vel = vector_len * unit_vector(
        state.free_stream_velocity_vector)
    orig = tip_pos - free_stream_vel
    axes_3d.quiver(*orig,
                   *free_stream_vel,
                   color=C.BLACK,
                   linewidth=PS.LINEWIDTH_c)
    axes_3d.text(*orig, f"{state.aero['airspeed']:.1f} m/s")