def branch(n): n1 = np.copy(n) n2 = np.copy(n) for i in range(len(n)): if n[i] == None: n1[i] = 0 n2[i] = 1 return n1, n2
def rotate(self, angle: float, x_center: float = 0., y_center: float = 0.) -> 'Airfoil': """ Rotates the airfoil clockwise by the specified amount, in radians. Rotates about the point (x_center, y_center), which is (0, 0) by default. Args: angle: Angle to rotate, counterclockwise, in radians. x_center: The x-coordinate of the center of rotation. y_center: The y-coordinate of the center of rotation. Returns: The rotated Airfoil. """ coordinates = np.copy(self.coordinates) ### Translate translation = np.array([x_center, y_center]) coordinates -= translation ### Rotate rotation_matrix = np.rotation_matrix_2D(angle=angle, ) coordinates = (rotation_matrix @ coordinates.T).T ### Translate coordinates += translation return Airfoil(name=self.name, coordinates=coordinates)
def add_control_surface( self, deflection: float = 0., hinge_point_x: float = 0.75, ) -> 'Airfoil': """ Returns a version of the airfoil with a control surface added at a given point. Implicitly repanels the airfoil as part of this operation. :param deflection: deflection angle [degrees]. Downwards-positive. :param hinge_point_x: location of the hinge, as a fraction of chord [float]. :return: The new airfoil. """ # Make the rotation matrix for the given angle. rotation_matrix = np.rotations.rotation_matrix_2D(-np.pi / 180 * deflection) # Find the hinge point hinge_point_y = self.local_camber(hinge_point_x) # Find the coordinates of a rotated airfoil rotated_airfoil = self.rotate( angle=-np.pi / 180 * deflection, x_center=hinge_point_x, y_center=hinge_point_y, ) # Merge the two sets of coordinates coordinates = np.copy(self.coordinates) is_past_hinge = self.x( ) > hinge_point_x # TODO fix hinge self-intersecting paneling issue for large deflection coordinates[is_past_hinge] = rotated_airfoil.coordinates[is_past_hinge] return Airfoil(name=self.name, coordinates=coordinates)