aerosandbox.aerodynamics.aero_3D ================================ .. py:module:: aerosandbox.aerodynamics.aero_3D Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/aerosandbox/aerodynamics/aero_3D/aero_buildup/index /autoapi/aerosandbox/aerodynamics/aero_3D/aero_buildup_submodels/index /autoapi/aerosandbox/aerodynamics/aero_3D/avl/index /autoapi/aerosandbox/aerodynamics/aero_3D/lifting_line/index /autoapi/aerosandbox/aerodynamics/aero_3D/linear_potential_flow/index /autoapi/aerosandbox/aerodynamics/aero_3D/nonlinear_lifting_line/index /autoapi/aerosandbox/aerodynamics/aero_3D/singularities/index /autoapi/aerosandbox/aerodynamics/aero_3D/vortex_lattice_method/index Classes ------- .. autoapisummary:: aerosandbox.aerodynamics.aero_3D.VortexLatticeMethod aerosandbox.aerodynamics.aero_3D.LiftingLine aerosandbox.aerodynamics.aero_3D.NonlinearLiftingLine aerosandbox.aerodynamics.aero_3D.AeroBuildup aerosandbox.aerodynamics.aero_3D.AVL Package Contents ---------------- .. py:class:: VortexLatticeMethod(airplane, op_point, xyz_ref = None, run_symmetric_if_possible = False, verbose = False, spanwise_resolution = 10, spanwise_spacing_function = np.cosspace, chordwise_resolution = 10, chordwise_spacing_function = np.cosspace, vortex_core_radius = 1e-08, align_trailing_vortices_with_wind = False) Bases: :py:obj:`aerosandbox.ExplicitAnalysis` An explicit (linear) vortex-lattice-method aerodynamics analysis. Usage example: >>> analysis = asb.VortexLatticeMethod( >>> airplane=my_airplane, >>> op_point=asb.OperatingPoint( >>> velocity=100, # m/s >>> alpha=5, # deg >>> beta=4, # deg >>> p=0.01, # rad/sec >>> q=0.02, # rad/sec >>> r=0.03, # rad/sec >>> ) >>> ) >>> aero_data = analysis.run() >>> analysis.draw() .. py:attribute:: airplane .. py:attribute:: op_point .. py:attribute:: xyz_ref :value: None .. py:attribute:: verbose :value: False .. py:attribute:: spanwise_resolution :value: 10 .. py:attribute:: spanwise_spacing_function .. py:attribute:: chordwise_resolution :value: 10 .. py:attribute:: chordwise_spacing_function .. py:attribute:: vortex_core_radius :value: 1e-08 .. py:attribute:: align_trailing_vortices_with_wind :value: False .. py:attribute:: run_symmetric :value: False .. py:method:: __repr__() .. py:method:: run() Computes the aerodynamic forces. Returns a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b', the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b', the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b', the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL', the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY', the sideforce coefficient [-]. This is in wind axes. - 'CD', the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl', the rolling coefficient [-], in body axes - 'Cm', the pitching coefficient [-], in body axes - 'Cn', the yawing coefficient [-], in body axes Nondimensional values are nondimensionalized using reference values in the VortexLatticeMethod.airplane object. .. py:method:: run_with_stability_derivatives(alpha=True, beta=True, p=True, q=True, r=True) Computes the aerodynamic forces and moments on the airplane, and the stability derivatives. Arguments essentially determine which stability derivatives are computed. If a stability derivative is not needed, leaving it False will speed up the computation. :param - alpha: If True, compute the stability derivatives with respect to the angle of attack (alpha). :type - alpha: bool :param - beta: If True, compute the stability derivatives with respect to the sideslip angle (beta). :type - beta: bool :param - p: If True, compute the stability derivatives with respect to the body-axis roll rate (p). :type - p: bool :param - q: If True, compute the stability derivatives with respect to the body-axis pitch rate (q). :type - q: bool :param - r: If True, compute the stability derivatives with respect to the body-axis yaw rate (r). :type - r: bool Returns: a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b', the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b', the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b', the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL', the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY', the sideforce coefficient [-]. This is in wind axes. - 'CD', the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl', the rolling coefficient [-], in body axes - 'Cm', the pitching coefficient [-], in body axes - 'Cn', the yawing coefficient [-], in body axes Along with additional keys, depending on the value of the `alpha`, `beta`, `p`, `q`, and `r` arguments. For example, if `alpha=True`, then the following additional keys will be present: - 'CLa', the lift coefficient derivative with respect to alpha [1/rad] - 'CDa', the drag coefficient derivative with respect to alpha [1/rad] - 'CYa', the sideforce coefficient derivative with respect to alpha [1/rad] - 'Cla', the rolling moment coefficient derivative with respect to alpha [1/rad] - 'Cma', the pitching moment coefficient derivative with respect to alpha [1/rad] - 'Cna', the yawing moment coefficient derivative with respect to alpha [1/rad] - 'x_np', the neutral point location in the x direction [m] Nondimensional values are nondimensionalized using reference values in the VortexLatticeMethod.airplane object. Data types: - The "L", "Y", "D", "l_b", "m_b", "n_b", "CL", "CY", "CD", "Cl", "Cm", and "Cn" keys are: - floats if the OperatingPoint object is not vectorized (i.e., if all attributes of OperatingPoint are floats, not arrays). - arrays if the OperatingPoint object is vectorized (i.e., if any attribute of OperatingPoint is an array). - The "F_g", "F_b", "F_w", "M_g", "M_b", and "M_w" keys are always lists, which will contain either floats or arrays, again depending on whether the OperatingPoint object is vectorized or not. .. py:method:: get_induced_velocity_at_points(points) Computes the induced velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the induced velocities at. Given in geometry axes. Returns: A Nx3 of the induced velocity at those points. Given in geometry axes. .. py:method:: get_velocity_at_points(points) Computes the velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the velocities at. Given in geometry axes. Returns: A Nx3 of the velocity at those points. Given in geometry axes. .. py:method:: calculate_streamlines(seed_points = None, n_steps = 300, length = None) Computes streamlines, starting at specific seed points. After running this function, a new instance variable `VortexLatticeFilaments.streamlines` is computed Uses simple forward-Euler integration with a fixed spatial stepsize (i.e., velocity vectors are normalized before ODE integration). After investigation, it's not worth doing fancier ODE integration methods (adaptive schemes, RK substepping, etc.), due to the near-singular conditions near vortex filaments. :param seed_points: A Nx3 ndarray that contains a list of points where streamlines are started. Will be :param auto-calculated if not specified.: :param n_steps: The number of individual streamline steps to trace. Minimum of 2. :param length: The approximate total length of the streamlines desired, in meters. Will be auto-calculated if :param not specified.: :returns: a 3D array with dimensions: (n_seed_points) x (3) x (n_steps). Consists of streamlines data. Result is also saved as an instance variable, VortexLatticeMethod.streamlines. :rtype: streamlines .. py:method:: draw(c = None, cmap = None, colorbar_label = None, show = True, show_kwargs = None, draw_streamlines=True, recalculate_streamlines=False, backend = 'pyvista') Draws the solution. Note: Must be called on a SOLVED AeroProblem object. To solve an AeroProblem, use opti.solve(). To substitute a solved solution, use ap = sol(ap). :return: .. py:class:: LiftingLine(airplane, op_point, xyz_ref = None, model_size = 'medium', run_symmetric_if_possible = False, verbose = False, spanwise_resolution = 4, spanwise_spacing_function = np.cosspace, vortex_core_radius = 1e-08, align_trailing_vortices_with_wind = False) Bases: :py:obj:`aerosandbox.ExplicitAnalysis` An implicit aerodynamics analysis based on lifting line theory, with modifications for nonzero sweep and dihedral + multiple wings. Nonlinear, and includes viscous effects based on 2D data. Usage example: >>> analysis = asb.LiftingLine( >>> airplane=my_airplane, >>> op_point=asb.OperatingPoint( >>> velocity=100, # m/s >>> alpha=5, # deg >>> beta=4, # deg >>> p=0.01, # rad/sec >>> q=0.02, # rad/sec >>> r=0.03, # rad/sec >>> ) >>> ) >>> outputs = analysis.run() .. py:attribute:: airplane .. py:attribute:: op_point .. py:attribute:: xyz_ref :value: None .. py:attribute:: model_size :value: 'medium' .. py:attribute:: verbose :value: False .. py:attribute:: spanwise_resolution :value: 4 .. py:attribute:: spanwise_spacing_function .. py:attribute:: vortex_core_radius :value: 1e-08 .. py:attribute:: align_trailing_vortices_with_wind :value: False .. py:attribute:: run_symmetric :value: False .. py:method:: __repr__() .. py:class:: AeroComponentResults .. py:attribute:: s_ref :type: float .. py:attribute:: c_ref :type: float .. py:attribute:: b_ref :type: float .. py:attribute:: op_point :type: aerosandbox.performance.OperatingPoint .. py:attribute:: F_g :type: List[Union[float, aerosandbox.geometry.np.ndarray]] .. py:attribute:: M_g :type: List[Union[float, aerosandbox.geometry.np.ndarray]] .. py:method:: __repr__() .. py:property:: F_b :type: List[Union[float, aerosandbox.geometry.np.ndarray]] An [x, y, z] list of forces in body axes [N] .. py:property:: F_w :type: List[Union[float, aerosandbox.geometry.np.ndarray]] An [x, y, z] list of forces in wind axes [N] .. py:property:: M_b :type: List[Union[float, aerosandbox.geometry.np.ndarray]] An [x, y, z] list of moments about body axes [Nm] .. py:property:: M_w :type: List[Union[float, aerosandbox.geometry.np.ndarray]] An [x, y, z] list of moments about wind axes [Nm] .. py:property:: L :type: Union[float, aerosandbox.geometry.np.ndarray] The lift force [N]. Definitionally, this is in wind axes. .. py:property:: Y :type: Union[float, aerosandbox.geometry.np.ndarray] The side force [N]. Definitionally, this is in wind axes. .. py:property:: D :type: Union[float, aerosandbox.geometry.np.ndarray] The drag force [N]. Definitionally, this is in wind axes. .. py:property:: l_b :type: Union[float, aerosandbox.geometry.np.ndarray] The rolling moment [Nm] in body axes. Positive is roll-right. .. py:property:: m_b :type: Union[float, aerosandbox.geometry.np.ndarray] The pitching moment [Nm] in body axes. Positive is nose-up. .. py:property:: n_b :type: Union[float, aerosandbox.geometry.np.ndarray] The yawing moment [Nm] in body axes. Positive is nose-right. .. py:method:: run() Computes the aerodynamic forces. Returns a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b', the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b', the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b', the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL', the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY', the sideforce coefficient [-]. This is in wind axes. - 'CD', the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl', the rolling coefficient [-], in body axes - 'Cm', the pitching coefficient [-], in body axes - 'Cn', the yawing coefficient [-], in body axes Nondimensional values are nondimensionalized using reference values in the LiftingLine.airplane object. Data types: - The "L", "Y", "D", "l_b", "m_b", "n_b", "CL", "CY", "CD", "Cl", "Cm", and "Cn" keys are: - floats if the OperatingPoint object is not vectorized (i.e., if all attributes of OperatingPoint are floats, not arrays). - arrays if the OperatingPoint object is vectorized (i.e., if any attribute of OperatingPoint is an array). - The "F_g", "F_b", "F_w", "M_g", "M_b", and "M_w" keys are always lists, which will contain either floats or arrays, again depending on whether the OperatingPoint object is vectorized or not. .. py:method:: run_with_stability_derivatives(alpha=True, beta=True, p=True, q=True, r=True) Computes the aerodynamic forces and moments on the airplane, and the stability derivatives. Arguments essentially determine which stability derivatives are computed. If a stability derivative is not needed, leaving it False will speed up the computation. :param - alpha: If True, compute the stability derivatives with respect to the angle of attack (alpha). :type - alpha: bool :param - beta: If True, compute the stability derivatives with respect to the sideslip angle (beta). :type - beta: bool :param - p: If True, compute the stability derivatives with respect to the body-axis roll rate (p). :type - p: bool :param - q: If True, compute the stability derivatives with respect to the body-axis pitch rate (q). :type - q: bool :param - r: If True, compute the stability derivatives with respect to the body-axis yaw rate (r). :type - r: bool Returns: a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b' : the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b' : the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b' : the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL' : the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY' : the sideforce coefficient [-]. This is in wind axes. - 'CD' : the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl' : the rolling coefficient [-], in body axes - 'Cm' : the pitching coefficient [-], in body axes - 'Cn' : the yawing coefficient [-], in body axes Along with additional keys, depending on the value of the `alpha`, `beta`, `p`, `q`, and `r` arguments. For example, if `alpha=True`, then the following additional keys will be present: - 'CLa' : the lift coefficient derivative with respect to alpha [1/rad] - 'CDa' : the drag coefficient derivative with respect to alpha [1/rad] - 'CYa' : the sideforce coefficient derivative with respect to alpha [1/rad] - 'Cla' : the rolling moment coefficient derivative with respect to alpha [1/rad] - 'Cma' : the pitching moment coefficient derivative with respect to alpha [1/rad] - 'Cna' : the yawing moment coefficient derivative with respect to alpha [1/rad] - 'x_np': the neutral point location in the x direction [m] Nondimensional values are nondimensionalized using reference values in the AeroBuildup.airplane object. Data types: - The "L", "Y", "D", "l_b", "m_b", "n_b", "CL", "CY", "CD", "Cl", "Cm", and "Cn" keys are: - floats if the OperatingPoint object is not vectorized (i.e., if all attributes of OperatingPoint are floats, not arrays). - arrays if the OperatingPoint object is vectorized (i.e., if any attribute of OperatingPoint is an array). - The "F_g", "F_b", "F_w", "M_g", "M_b", and "M_w" keys are always lists, which will contain either floats or arrays, again depending on whether the OperatingPoint object is vectorized or not. .. py:method:: wing_aerodynamics() .. py:method:: get_induced_velocity_at_points(points, vortex_strengths = None) Computes the induced velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the induced velocities at. Given in geometry axes. Returns: A Nx3 of the induced velocity at those points. Given in geometry axes. .. py:method:: get_velocity_at_points(points, vortex_strengths = None) Computes the velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the velocities at. Given in geometry axes. Returns: A Nx3 of the velocity at those points. Given in geometry axes. .. py:method:: calculate_fuselage_influences(points) .. py:method:: calculate_streamlines(seed_points = None, n_steps = 300, length = None) Computes streamlines, starting at specific seed points. After running this function, a new instance variable `VortexLatticeFilaments.streamlines` is computed Uses simple forward-Euler integration with a fixed spatial stepsize (i.e., velocity vectors are normalized before ODE integration). After investigation, it's not worth doing fancier ODE integration methods (adaptive schemes, RK substepping, etc.), due to the near-singular conditions near vortex filaments. :param seed_points: A Nx3 ndarray that contains a list of points where streamlines are started. Will be :param auto-calculated if not specified.: :param n_steps: The number of individual streamline steps to trace. Minimum of 2. :param length: The approximate total length of the streamlines desired, in meters. Will be auto-calculated if :param not specified.: :returns: a 3D array with dimensions: (n_seed_points) x (3) x (n_steps). Consists of streamlines data. Result is also saved as an instance variable, VortexLatticeMethod.streamlines. :rtype: streamlines .. py:method:: draw(c = None, cmap = None, colorbar_label = None, show = True, show_kwargs = None, draw_streamlines=True, recalculate_streamlines=False, backend = 'pyvista') Draws the solution. Note: Must be called on a SOLVED AeroProblem object. To solve an AeroProblem, use opti.solve(). To substitute a solved solution, use ap = sol(ap). :return: .. py:class:: NonlinearLiftingLine(airplane, op_point, xyz_ref = None, run_symmetric_if_possible = False, verbose = False, spanwise_resolution=8, spanwise_spacing_function = np.cosspace, vortex_core_radius = 1e-08, align_trailing_vortices_with_wind = False) Bases: :py:obj:`aerosandbox.ImplicitAnalysis` An implicit aerodynamics analysis based on lifting line theory, with modifications for nonzero sweep and dihedral + multiple wings. Nonlinear, and includes viscous effects based on 2D data. Usage example: >>> analysis = asb.NonlinearLiftingLine( >>> airplane=my_airplane, >>> op_point=asb.OperatingPoint( >>> velocity=100, # m/s >>> alpha=5, # deg >>> beta=4, # deg >>> p=0.01, # rad/sec >>> q=0.02, # rad/sec >>> r=0.03, # rad/sec >>> ) >>> ) >>> outputs = analysis.run() .. py:attribute:: airplane .. py:attribute:: op_point .. py:attribute:: xyz_ref :value: None .. py:attribute:: verbose :value: False .. py:attribute:: spanwise_resolution :value: 8 .. py:attribute:: spanwise_spacing_function .. py:attribute:: vortex_core_radius :value: 1e-08 .. py:attribute:: align_trailing_vortices_with_wind :value: False .. py:attribute:: run_symmetric :value: False .. py:method:: __repr__() .. py:method:: run(solve = True) Computes the aerodynamic forces. Returns a dictionary with keys: - 'residuals': a list of residuals for each horseshoe element - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b', the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b', the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b', the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL', the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY', the sideforce coefficient [-]. This is in wind axes. - 'CD', the drag coefficient [-]. Definitionally, this is in wind axes. - 'CDi' the induced drag coefficient - 'CDp' the profile drag coefficient - 'Cl', the rolling coefficient [-], in body axes - 'Cm', the pitching coefficient [-], in body axes - 'Cn', the yawing coefficient [-], in body axes Nondimensional values are nondimensionalized using reference values in the VortexLatticeMethod.airplane object. .. py:method:: get_induced_velocity_at_points(points, vortex_strengths = None) Computes the induced velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the induced velocities at. Given in geometry axes. Returns: A Nx3 of the induced velocity at those points. Given in geometry axes. .. py:method:: get_velocity_at_points(points, vortex_strengths = None) Computes the velocity at a set of points in the flowfield. :param points: A Nx3 array of points that you would like to know the velocities at. Given in geometry axes. Returns: A Nx3 of the velocity at those points. Given in geometry axes. .. py:method:: calculate_fuselage_influences(points) .. py:method:: calculate_streamlines(seed_points = None, n_steps = 300, length = None) Computes streamlines, starting at specific seed points. After running this function, a new instance variable `VortexLatticeFilaments.streamlines` is computed Uses simple forward-Euler integration with a fixed spatial stepsize (i.e., velocity vectors are normalized before ODE integration). After investigation, it's not worth doing fancier ODE integration methods (adaptive schemes, RK substepping, etc.), due to the near-singular conditions near vortex filaments. :param seed_points: A Nx3 ndarray that contains a list of points where streamlines are started. Will be :param auto-calculated if not specified.: :param n_steps: The number of individual streamline steps to trace. Minimum of 2. :param length: The approximate total length of the streamlines desired, in meters. Will be auto-calculated if :param not specified.: :returns: a 3D array with dimensions: (n_seed_points) x (3) x (n_steps). Consists of streamlines data. Result is also saved as an instance variable, VortexLatticeMethod.streamlines. :rtype: streamlines .. py:method:: draw(c = None, cmap = None, colorbar_label = None, show = True, show_kwargs = None, draw_streamlines=True, recalculate_streamlines=False, backend = 'pyvista') Draws the solution. Note: Must be called on a SOLVED AeroProblem object. To solve an AeroProblem, use opti.solve(). To substitute a solved solution, use ap = sol(ap). :return: .. py:class:: AeroBuildup(airplane, op_point, xyz_ref = None, model_size = 'small', include_wave_drag = True) Bases: :py:obj:`aerosandbox.ExplicitAnalysis` A workbook-style aerodynamics buildup. Example usage: >>> import aerosandbox as asb >>> ab = asb.AeroBuildup( # This sets up the analysis, but doesn't execute calculation >>> airplane=my_airplane, # type: asb.Airplane >>> op_point=my_operating_point, # type: asb.OperatingPoint >>> xyz_ref=[0.1, 0.2, 0.3], # Moment reference and center of rotation. >>> ) >>> aero = ab.run() # This executes the actual aero analysis. >>> aero_with_stability_derivs = ab.run_with_stability_derivatives() # Same, but also gets stability derivatives. .. py:attribute:: default_analysis_specific_options This is part of AeroSandbox's "analysis-specific options" feature, which lets you "tag" geometry objects with flags that change how different analyses act on them. This variable, `default_analysis_specific_options`, allows you to specify default values for options that can be used for specific problems. This should be a dictionary, where: * keys are the geometry-like types that you might be interested in defining parameters for. * values are dictionaries, where: * keys are strings that label a given option * values are anything. These are used as the default values, in the event that the associated geometry doesn't override those. An example of what this variable might look like, for a vortex-lattice method aerodynamic analysis: >>> default_analysis_specific_options = { >>> Airplane: dict( >>> profile_drag_coefficient=0 >>> ), >>> Wing : dict( >>> wing_level_spanwise_spacing=True, >>> spanwise_resolution=12, >>> spanwise_spacing="cosine", >>> chordwise_resolution=12, >>> chordwise_spacing="cosine", >>> component=None, # type: int >>> no_wake=False, >>> no_alpha_beta=False, >>> no_load=False, >>> drag_polar=dict( >>> CL1=0, >>> CD1=0, >>> CL2=0, >>> CD2=0, >>> CL3=0, >>> CD3=0, >>> ), >>> ) >>> } .. py:attribute:: airplane .. py:attribute:: op_point .. py:attribute:: xyz_ref :value: None .. py:attribute:: model_size :value: 'small' .. py:attribute:: include_wave_drag :value: True .. py:method:: __repr__() .. py:class:: AeroComponentResults .. py:attribute:: s_ref :type: float .. py:attribute:: c_ref :type: float .. py:attribute:: b_ref :type: float .. py:attribute:: op_point :type: aerosandbox.performance.OperatingPoint .. py:attribute:: F_g :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] .. py:attribute:: M_g :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] .. py:attribute:: span_effective :type: float .. py:attribute:: oswalds_efficiency :type: float .. py:method:: __repr__() .. py:property:: F_b :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] An [x, y, z] list of forces in body axes [N] .. py:property:: F_w :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] An [x, y, z] list of forces in wind axes [N] .. py:property:: M_b :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] An [x, y, z] list of moments about body axes [Nm] .. py:property:: M_w :type: List[Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray]] An [x, y, z] list of moments about wind axes [Nm] .. py:property:: L :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The lift force [N]. Definitionally, this is in wind axes. .. py:property:: Y :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The side force [N]. Definitionally, this is in wind axes. .. py:property:: D :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The drag force [N]. Definitionally, this is in wind axes. .. py:property:: l_b :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The rolling moment [Nm] in body axes. Positive is roll-right. .. py:property:: m_b :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The pitching moment [Nm] in body axes. Positive is nose-up. .. py:property:: n_b :type: Union[float, aerosandbox.aerodynamics.aero_3D.aero_buildup_submodels.fuselage_aerodynamics_utilities.np.ndarray] The yawing moment [Nm] in body axes. Positive is nose-right. .. py:method:: run() Computes the aerodynamic forces and moments on the airplane. Returns: a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b', the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b', the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b', the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL', the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY', the sideforce coefficient [-]. This is in wind axes. - 'CD', the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl', the rolling coefficient [-], in body axes - 'Cm', the pitching coefficient [-], in body axes - 'Cn', the yawing coefficient [-], in body axes Nondimensional values are nondimensionalized using reference values in the AeroBuildup.airplane object. Data types: - The "L", "Y", "D", "l_b", "m_b", "n_b", "CL", "CY", "CD", "Cl", "Cm", and "Cn" keys are: - floats if the OperatingPoint object is not vectorized (i.e., if all attributes of OperatingPoint are floats, not arrays). - arrays if the OperatingPoint object is vectorized (i.e., if any attribute of OperatingPoint is an array). - The "F_g", "F_b", "F_w", "M_g", "M_b", and "M_w" keys are always lists, which will contain either floats or arrays, again depending on whether the OperatingPoint object is vectorized or not. .. py:method:: run_with_stability_derivatives(alpha=True, beta=True, p=True, q=True, r=True) Computes the aerodynamic forces and moments on the airplane, and the stability derivatives. Arguments essentially determine which stability derivatives are computed. If a stability derivative is not needed, leaving it False will speed up the computation. :param - alpha: If True, compute the stability derivatives with respect to the angle of attack (alpha). :type - alpha: bool :param - beta: If True, compute the stability derivatives with respect to the sideslip angle (beta). :type - beta: bool :param - p: If True, compute the stability derivatives with respect to the body-axis roll rate (p). :type - p: bool :param - q: If True, compute the stability derivatives with respect to the body-axis pitch rate (q). :type - q: bool :param - r: If True, compute the stability derivatives with respect to the body-axis yaw rate (r). :type - r: bool Returns: a dictionary with keys: - 'F_g' : an [x, y, z] list of forces in geometry axes [N] - 'F_b' : an [x, y, z] list of forces in body axes [N] - 'F_w' : an [x, y, z] list of forces in wind axes [N] - 'M_g' : an [x, y, z] list of moments about geometry axes [Nm] - 'M_b' : an [x, y, z] list of moments about body axes [Nm] - 'M_w' : an [x, y, z] list of moments about wind axes [Nm] - 'L' : the lift force [N]. Definitionally, this is in wind axes. - 'Y' : the side force [N]. This is in wind axes. - 'D' : the drag force [N]. Definitionally, this is in wind axes. - 'l_b' : the rolling moment, in body axes [Nm]. Positive is roll-right. - 'm_b' : the pitching moment, in body axes [Nm]. Positive is pitch-up. - 'n_b' : the yawing moment, in body axes [Nm]. Positive is nose-right. - 'CL' : the lift coefficient [-]. Definitionally, this is in wind axes. - 'CY' : the sideforce coefficient [-]. This is in wind axes. - 'CD' : the drag coefficient [-]. Definitionally, this is in wind axes. - 'Cl' : the rolling coefficient [-], in body axes - 'Cm' : the pitching coefficient [-], in body axes - 'Cn' : the yawing coefficient [-], in body axes Along with additional keys, depending on the value of the `alpha`, `beta`, `p`, `q`, and `r` arguments. For example, if `alpha=True`, then the following additional keys will be present: - 'CLa' : the lift coefficient derivative with respect to alpha [1/rad] - 'CDa' : the drag coefficient derivative with respect to alpha [1/rad] - 'CYa' : the sideforce coefficient derivative with respect to alpha [1/rad] - 'Cla' : the rolling moment coefficient derivative with respect to alpha [1/rad] - 'Cma' : the pitching moment coefficient derivative with respect to alpha [1/rad] - 'Cna' : the yawing moment coefficient derivative with respect to alpha [1/rad] - 'x_np': the neutral point location in the x direction [m] Nondimensional values are nondimensionalized using reference values in the AeroBuildup.airplane object. Data types: - The "L", "Y", "D", "l_b", "m_b", "n_b", "CL", "CY", "CD", "Cl", "Cm", and "Cn" keys are: - floats if the OperatingPoint object is not vectorized (i.e., if all attributes of OperatingPoint are floats, not arrays). - arrays if the OperatingPoint object is vectorized (i.e., if any attribute of OperatingPoint is an array). - The "F_g", "F_b", "F_w", "M_g", "M_b", and "M_w" keys are always lists, which will contain either floats or arrays, again depending on whether the OperatingPoint object is vectorized or not. .. py:method:: wing_aerodynamics(wing, include_induced_drag = True) Estimates the aerodynamic forces, moments, and derivatives on a wing in isolation. Moments are given with the reference at Wing [0, 0, 0]. :param wing: A Wing object that you wish to analyze. :param op_point: The OperatingPoint that you wish to analyze the fuselage at. Returns: .. py:method:: fuselage_aerodynamics(fuselage, include_induced_drag = True) Estimates the aerodynamic forces, moments, and derivatives on a fuselage in isolation. Assumes: * The fuselage is a body of revolution aligned with the x_b axis. * The angle between the nose and the freestream is less than 90 degrees. Moments are given with the reference at Fuselage [0, 0, 0]. Uses methods from Jorgensen, Leland Howard. "Prediction of Static Aerodynamic Characteristics for Slender Bodies Alone and with Lifting Surfaces to Very High Angles of Attack". NASA TR R-474. 1977. :param fuselage: A Fuselage object that you wish to analyze. Returns: .. py:class:: AVL(airplane, op_point, xyz_ref = None, avl_command = 'avl', verbose = False, timeout = 5, working_directory = None, ground_effect = False, ground_effect_height = 0) Bases: :py:obj:`aerosandbox.common.ExplicitAnalysis` An interface to AVL, a 3D vortex lattice aerodynamics code developed by Mark Drela at MIT. Requires AVL to be on your computer; AVL is available here: https://web.mit.edu/drela/Public/web/avl/ It is recommended (but not required) that you add AVL to your system PATH environment variable such that it can be called with the command `avl`. If this is not the case, you need to specify the path to your AVL executable using the `avl_command` argument of the constructor. Usage example: >>> avl = asb.AVL( >>> airplane=my_airplane, >>> op_point=asb.OperatingPoint( >>> velocity=100, # m/s >>> alpha=5, # deg >>> beta=4, # deg >>> p=0.01, # rad/sec >>> q=0.02, # rad/sec >>> r=0.03, # rad/sec >>> ) >>> ) >>> outputs = avl.run() .. py:attribute:: default_analysis_specific_options This is part of AeroSandbox's "analysis-specific options" feature, which lets you "tag" geometry objects with flags that change how different analyses act on them. This variable, `default_analysis_specific_options`, allows you to specify default values for options that can be used for specific problems. This should be a dictionary, where: * keys are the geometry-like types that you might be interested in defining parameters for. * values are dictionaries, where: * keys are strings that label a given option * values are anything. These are used as the default values, in the event that the associated geometry doesn't override those. An example of what this variable might look like, for a vortex-lattice method aerodynamic analysis: >>> default_analysis_specific_options = { >>> Airplane: dict( >>> profile_drag_coefficient=0 >>> ), >>> Wing : dict( >>> wing_level_spanwise_spacing=True, >>> spanwise_resolution=12, >>> spanwise_spacing="cosine", >>> chordwise_resolution=12, >>> chordwise_spacing="cosine", >>> component=None, # type: int >>> no_wake=False, >>> no_alpha_beta=False, >>> no_load=False, >>> drag_polar=dict( >>> CL1=0, >>> CD1=0, >>> CL2=0, >>> CD2=0, >>> CL3=0, >>> CD3=0, >>> ), >>> ) >>> } .. py:attribute:: AVL_spacing_parameters .. py:attribute:: airplane .. py:attribute:: op_point .. py:attribute:: xyz_ref :value: None .. py:attribute:: avl_command :value: 'avl' .. py:attribute:: verbose :value: False .. py:attribute:: timeout :value: 5 .. py:attribute:: working_directory :value: None .. py:attribute:: ground_effect :value: False .. py:attribute:: ground_effect_height :value: 0 .. py:method:: __repr__() .. py:method:: open_interactive() Opens a new terminal window and runs AVL interactively. This is useful for detailed analysis or debugging. Returns: None .. py:method:: run(run_command = None) Private function to run AVL. Args: run_command: A string with any AVL keystroke inputs that you'd like. By default, you start off within the OPER menu. All of the inputs indicated in the constructor have been set already, but you can override them here ( for this run only) if you want. Returns: A dictionary containing all of your results. .. py:method:: _default_keystroke_file_contents() .. py:method:: write_avl(filepath = None) Writes a .avl file corresponding to this airplane to a filepath. For use with the AVL vortex-lattice-method aerodynamics analysis tool by Mark Drela at MIT. AVL is available here: https://web.mit.edu/drela/Public/web/avl/ :param filepath: filepath (including the filename and .avl extension) [string] If None, this function returns the .avl file as a string. Returns: None .. py:method:: write_avl_bfile(fuselage, filepath = None, include_name = True) :staticmethod: Writes an AVL-compatible BFILE corresponding to this fuselage to a filepath. For use with the AVL vortex-lattice-method aerodynamics analysis tool by Mark Drela at MIT. AVL is available here: https://web.mit.edu/drela/Public/web/avl/ :param filepath: filepath (including the filename and .avl extension) [string] If None, this function returns the would-be file contents as a string. :param include_name: Should the name of the fuselage be included in the .dat file? (This should be True for use with AVL.) Returns: .. py:method:: parse_unformatted_data_output(s, data_identifier = ' = ', cast_outputs_to_float = True, overwrite = None) :staticmethod: Parses a (multiline) string of unformatted data into a nice and tidy dictionary. The expected input string looks like what you might get as an output from AVL (or many other Drela codes), which may list data in ragged order. An example input `s` that you might want to parse could look like the following: ``` Standard axis orientation, X fwd, Z down Run case: -unnamed- Alpha = 0.43348 pb/2V = -0.00000 p'b/2V = -0.00000 Beta = 0.00000 qc/2V = 0.00000 Mach = 0.003 rb/2V = -0.00000 r'b/2V = -0.00000 CXtot = -0.02147 Cltot = 0.00000 Cl'tot = 0.00000 CYtot = 0.00000 Cmtot = 0.28149 CZtot = -1.01474 Cntot = -0.00000 Cn'tot = -0.00000 CLtot = 1.01454 CDtot = 0.02915 CDvis = 0.00000 CDind = 0.0291513 CLff = 1.00050 CDff = 0.0297201 | Trefftz CYff = 0.00000 e = 0.9649 | Plane ``` Here, this function will go through this string and extract each key-value pair, as denoted by the data identifier (by default, " = "). It will pull the next whole word without spaces to the left as the key, and it will pull the next whole word without spaces to the right as the value. Together, these will be returned as a Dict. So, the output for the input above would be: { 'Alpha' : 0.43348, 'pb/2V' : -0.00000, 'p'b/2V' : -0.00000, 'Beta' : 0.00000, # and so on... } :param s: The input string to identify. Can be multiline. :param data_identifier: The triggering substring for a new key-value pair. By default, it's " = ", :param which is convention in many output files from Mark Drela's codes. Be careful if you decide to change this: :param to "=": :type to "=": '=======' :param as you could pick up on heading separators: :type as you could pick up on heading separators: '=======' :param cast_outputs_to_float: If this boolean flag is set true, the values of the key-value pairs are cast to :param floating-point numbers before returning: :type floating-point numbers before returning: as opposed to the default type, string :param cast: :param a NaN is returned (guaranteeing that you can do floating-point math with the outputs in downstream: :param applications.): :param overwrite: Determines the behavior if you find a key that's already in the dictionary. * By default, value is None. In this case, an error is raised. * If you set it to True, the new value will overwrite the old one. Thus, your dictionary will have the last matching value from the string. * If you set it to False, the new value will be discarded. Thus, your dictionary will have the first matching value from the string. Returns: A dictionary of key-value pairs, corresponding to the unformatted data in the input string. Keys are strings, values are floats if `cast_outputs_to_float` is True, otherwise also strings.