Source code for openaerostruct.aerodynamics.convert_velocity

import numpy as np

import openmdao.api as om


[docs] class ConvertVelocity(om.ExplicitComponent): """ Convert the freestream velocity magnitude into a velocity vector at each evaluation point. In this case, each of the panels sees the same velocity. This really just helps us set up the velocities for use in the VLM analysis. Parameters ---------- alpha : float The angle of attack for the aircraft (all lifting surfaces) in degrees. beta : float The sideslip angle for the aircraft (all lifting surfaces) in degrees. v : float The freestream velocity magnitude. rotational_velocities[system_size, 3] : numpy array The rotated freestream velocities at each evaluation point for all lifting surfaces. system_size is the sum of the count of all panels for all lifting surfaces. Returns ------- freestream_velocities[system_size, 3] : numpy array The rotated freestream velocities at each evaluation point for all lifting surfaces. system_size is the sum of the count of all panels for all lifting surfaces. """ def initialize(self): self.options.declare("surfaces", types=list) self.options.declare( "rotational", False, types=bool, desc="Set to True to turn on support for computing angular velocities" ) def setup(self): surfaces = self.options["surfaces"] rotational = self.options["rotational"] system_size = 0 sizes = [] # Loop through each surface and cumulatively add the number of panels # to obtain system_size. for surface in surfaces: mesh = surface["mesh"] nx = mesh.shape[0] ny = mesh.shape[1] size = (nx - 1) * (ny - 1) system_size += size sizes.append(size) self.system_size = system_size self.add_input("alpha", val=0.0, units="deg", tags=["mphys_input"]) self.add_input("beta", val=0.0, units="deg", tags=["mphys_input"]) self.add_input("v", val=1.0, units="m/s", tags=["mphys_input"]) if rotational: self.add_input("rotational_velocities", shape=(system_size, 3), units="m/s") self.add_output("freestream_velocities", shape=(system_size, 3), units="m/s") self.declare_partials("freestream_velocities", "alpha") self.declare_partials("freestream_velocities", "beta") self.declare_partials("freestream_velocities", "v") if rotational: nn = 3 * system_size row_col = np.arange(nn) val = np.ones((nn,)) self.declare_partials("freestream_velocities", "rotational_velocities", rows=row_col, cols=row_col, val=val) def compute(self, inputs, outputs): # Rotate the freestream velocities based on the angle of attack and the sideslip angle. alpha = inputs["alpha"][0] * np.pi / 180.0 beta = inputs["beta"][0] * np.pi / 180.0 cosa = np.cos(alpha) sina = np.sin(alpha) cosb = np.cos(beta) sinb = np.sin(beta) v_inf = inputs["v"][0] * np.array([cosa * cosb, -sinb, sina * cosb]) outputs["freestream_velocities"][:, :] = v_inf if self.options["rotational"]: outputs["freestream_velocities"][:, :] += inputs["rotational_velocities"] def compute_partials(self, inputs, J): alpha = inputs["alpha"][0] * np.pi / 180.0 beta = inputs["beta"][0] * np.pi / 180.0 cosa = np.cos(alpha) sina = np.sin(alpha) cosb = np.cos(beta) sinb = np.sin(beta) J["freestream_velocities", "v"] = np.tile(np.array([cosa * cosb, -sinb, sina * cosb]), self.system_size) J["freestream_velocities", "alpha"] = np.tile( inputs["v"][0] * np.array([-sina * cosb, 0.0, cosa * cosb]) * np.pi / 180.0, self.system_size ) J["freestream_velocities", "beta"] = np.tile( inputs["v"][0] * np.array([-cosa * sinb, -cosb, -sina * sinb]) * np.pi / 180.0, self.system_size )