### Setup Development Environment and Install Dependencies (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/CONTRIBUTING.md Creates a virtual environment, activates it, installs necessary Python packages for development and running simulations. Includes commands for both Mac/Linux and Windows. ```shell # On Mac or Linux: python -m venv .venv source .venv/bin/activate # On Windows: python -m venv .venv .venv\Scripts\activate python -m pip install --upgrade pip setuptools wheel pip install -r requirements.txt pip install -r requirements_dev.txt deactivate ``` -------------------------------- ### Python Module-Level Docstring for __init__.py Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Example of a module-level docstring for a public package's __init__.py file. It provides a high-level overview of the package's contents, listing subpackages, directories, and modules. ```python """Contains the geometry classes. **Contains the following subpackages:** None **Contains the following directories:** None **Contains the following modules:** airfoil.py: Contains the Airfoil class. airplane.py: Contains the Airplane class. wing.py: Contains the Wing class. wing_cross_section.py: Contains the WingCrossSection class. """ ``` -------------------------------- ### Install Dependencies from Requirements File (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/README.md Installs all necessary Python packages listed in the 'requirements.txt' file. This is typically done after downloading the source code of Ptera Software. It ensures all required libraries are available for the software to run correctly. ```shell pip install -r requirements.txt ``` -------------------------------- ### Install Development Dependencies from Requirements File (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/README.md Installs Python packages listed in 'requirements_dev.txt', which are necessary for development and making significant changes to the software. Use this command in addition to the standard requirements if you plan to contribute to the codebase. ```shell pip install -r requirements_dev.txt ``` -------------------------------- ### Python Common Type Hinting Patterns Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Provides examples of common type hinting patterns used in Python, covering simple types, array-like inputs, NumPy arrays, class references, optional types, unions, and collections. ```python # Simple types param: str param: bool param: bool | np.bool_ # Accepts both Python and numpy bools param: int param: float | int # Array-like (user input) param: np.ndarray | Sequence[float | int] param: np.ndarray | Sequence[float] param: np.ndarray | Sequence[Sequence[float | int]] # Already numpy arrays param: np.ndarray # Classes param: ClassName # Same module param: module_alias.ClassName # Different module -> "ClassName" # Self-reference # Optional/Union param: Type | None param: Type1 | Type2 # Collections -> list[np.ndarray] -> list[ClassName] ``` -------------------------------- ### Install Ptera Software Package (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/README.md Installs the Ptera Software package from PyPI, making its functions available for import into your Python projects. This is the recommended method for using Ptera Software as a dependency in your own applications. ```shell pip install pterasoftware ``` -------------------------------- ### Importing Type Hint Dependencies Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Imports necessary for type hinting, including Sequence from collections.abc and numpy. ```python from collections.abc import Sequence import numpy as np ``` -------------------------------- ### Python Function Docstring with Array Parameters Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md An example of a Python function docstring for an internal function `_get_mcl_points`. It details the function's purpose, parameters (including type hints and descriptions for array-like inputs), and return values. ```python def _get_mcl_points( inner_airfoil: airfoil_mod.Airfoil, outer_airfoil: airfoil_mod.Airfoil, chordwise_coordinates: np.ndarray, ) -> list[np.ndarray]: """Takes in the inner and outer Airfoils of a wing section and its normalized chordwise coordinates. It returns a list of four column vectors containing the normalized components of the positions of points along the mean camber line (MCL) (in each Airfoil's axes, relative to each Airfoil's leading point). :param inner_airfoil: The wing section's inner Airfoil. :param outer_airfoil: The wing section's outer Airfoil. :param chordwise_coordinates: A (N,) ndarray of floats for the normalized chordwise coordinates where we'd like to sample each Airfoil's MCL. The values are normalized from 0.0 to 1.0 and are unitless. :return: A list of four (N,1) ndarrays of floats, where N is the number of points at which we'd like to sample each Airfoil's MCL. The ndarrays contain components of the positions of points along each Airfoil's MCL. In order, the ndarrays returned are, (1) the inner Airfoil's MCL points' y-components, (2) the inner Airfoil's MCL points' x-components (3) the outer Airfoil's MCL points' y-components, and (4) the outer Airfoil's MCL points' x-components. The values are normalized from 0.0 to 1.0 and are unitless. """ ``` -------------------------------- ### Python Module Docstring: Public Modules Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Shows the docstring format for public modules like `airfoil.py` or `wing.py`. It starts with a brief description and lists public classes and functions, including brief descriptions for each class. Uses blank lines for separation. ```python """Contains the Airfoil class. **Contains the following classes:** Airfoil: A class used to contain the Airfoil of a WingCrossSection. **Contains the following functions:** None """ ``` -------------------------------- ### Python Module Docstring: Public Package __init__.py Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Illustrates the structure for `__init__.py` files in public packages. It includes a brief description followed by lists of subpackages, directories, and modules, each with a one-line description. Blank lines enhance readability. ```python """Contains the geometry classes. **Contains the following subpackages:** None **Contains the following directories:** None **Contains the following modules:** airfoil.py: Contains the Airfoil class. airplane.py: Contains the Airplane class. wing.py: Contains the Wing class. wing_cross_section.py: Contains the WingCrossSection class. """ ``` -------------------------------- ### Run Steady Horseshoe Solver with PteraSoftware (Python) Source: https://github.com/camurban/pterasoftware/blob/main/README.md This Python code demonstrates how to set up and run the steady horseshoe vortex lattice method solver for an airplane with custom geometry using the pterasoftware library. It requires the pterasoftware package to be installed. The input is a defined airplane geometry and operating point, and the output is a visualization of the lift distribution. ```python import pterasoftware as ps airplane = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil( name="naca2412", ), num_spanwise_panels=8, control_surface_symmetry_type="asymmetric", spanwise_spacing="cosine", ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil( name="naca2412", ), num_spanwise_panels=None, Lp_Wcsp_Lpp=(0, 5, 0), control_surface_symmetry_type="asymmetric", ), ], symmetric=True, symmetryNormal_G=(0, 1, 0), symmetryPoint_G_Cg=(0, 0, 0), ), ], ) operating_point = ps.operating_point.OperatingPoint() problem = ps.problems.SteadyProblem( airplanes=[airplane], operating_point=operating_point ) solver = ( ps.steady_horseshoe_vortex_lattice_method.SteadyHorseshoeVortexLatticeMethodSolver( steady_problem=problem ) ) solver.run() ps.output.draw(solver=solver, scalar_type="lift", show_streamlines=True) ``` -------------------------------- ### Python Property Docstring Template Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md A template for documenting Python properties using docstrings. It includes a concise description of what the property represents and a detailed return description specifying type, shape, and units. ```python @property def property_name(self) -> ReturnType: """Short description of what the property represents. :return: Description of what is returned, including type, shape, units. """ ``` -------------------------------- ### Module Alias Pattern for Imports Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Demonstrates the pattern of importing modules with aliases to avoid circular dependencies and improve code organization. This is particularly useful in package structures. ```python from . import airfoil as airfoil_mod from . import wing as wing_mod from . import wing_cross_section as wing_cross_section_mod ``` -------------------------------- ### Optional Attribute Type Hinting Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Demonstrates how to use type hints for class attributes that are initialized to None and populated later. This pattern is useful for attributes that are not immediately available upon object instantiation. ```python class Solver: def __init__(self): # Attribute that will be populated before use self.current_airplanes: list[geometry.airplane.Airplane] | None = None ``` -------------------------------- ### Python Method with Optional Return Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Demonstrates a Python method that can optionally return data or None based on a boolean parameter. It includes type hints for parameters and return values, and a docstring explaining its behavior and return types. ```python def get_plottable_data(self, show: bool = False) -> list[np.ndarray] | None: """Returns plottable data for this Airfoil's outline and mean camber line. :param show: Determines whether to display the plot. Can be a bool or a numpy bool, and will be converted internally to a bool. If True, the method displays the plot and returns None. If False, the method returns the data without displaying. The default is False. :return: A list of two ndarrays containing the outline and MCL data, or None if show is True. """ # Method implementation would go here ``` -------------------------------- ### Formation Flight Simulation with Pterasoftware Source: https://context7.com/camurban/pterasoftware/llms.txt This example illustrates how to simulate formation flight with multiple airplanes using Pterasoftware. It involves defining individual airplane geometries, their movements, and an operating point. The simulation is then set up as an unsteady problem and executed using the Unsteady Ring Vortex Lattice Method solver. Finally, the results are animated. ```python import pterasoftware as ps # Create first airplane airplane1 = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca2412"), num_spanwise_panels=10, chord=1.0, ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca2412"), Lp_Wcsp_Lpp=(0.0, 5.0, 0.0), ), ], symmetric=True, ), ], name="Leader", Cg_GP1_CgP1=(0.0, 0.0, 0.0), ) # Create second airplane with offset position airplane2 = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), num_spanwise_panels=10, chord=0.8, ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), Lp_Wcsp_Lpp=(0.0, 4.0, 0.0), ), ], symmetric=True, ), ], name="Follower", Cg_GP1_CgP1=(3.0, 2.0, 0.0), ) # Create movements for both airplanes airplane1_movement = ps.movements.airplane_movement.AirplaneMovement( base_airplane=airplane1, wing_movements=[], ) airplane2_movement = ps.movements.airplane_movement.AirplaneMovement( base_airplane=airplane2, wing_movements=[], ) operating_point = ps.operating_point.OperatingPoint(vCg__E=12.0, alpha=2.0) operating_point_movement = ps.movements.operating_point_movement.OperatingPointMovement( base_operating_point=operating_point ) # Create movement with multiple airplanes movement = ps.movements.movement.Movement( airplane_movements=[airplane1_movement, airplane2_movement], operating_point_movement=operating_point_movement, num_cycles=2, ) problem = ps.problems.UnsteadyProblem(movement=movement) solver = ps.unsteady_ring_vortex_lattice_method.UnsteadyRingVortexLatticeMethodSolver( unsteady_problem=problem ) solver.run(logging_level="Warning", prescribed_wake=True) ps.output.animate(unsteady_solver=solver, scalar_type="lift") ``` -------------------------------- ### Initialize Airfoil Object (Python) Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Initializes an Airfoil object with an optional name, outline points, and resampling parameters. It handles default values for name and resampling, and accepts various array-like types for outline points. ```python def __init__( self, name: str = "NACA0012", outline_A_lp: np.ndarray | Sequence[Sequence[float | int]] | None = None, resample: bool = True, n_points_per_side: int = 400, ) -> None: """The initialization method. :param name: The name of the Airfoil. It should correspond to the name of a file the airfoils directory, or to a valid NACA 4-series airfoil (once converted to lower-case and stripped of leading and trailing whitespace) unless you are passing in your own array of points using outline_A_lp. Note that NACA0000 isn't a valid NACA-series airfoil. The default is "NACA0012". :param outline_A_lp: An array-like object of numbers (int or float) with shape (N,2) representing the 2D points making up the Airfoil's outline (in airfoil axes, relative to the leading point). If you wish to load coordinates from the airfoils directory, leave this as None, which is the default. Can be a tuple, list, or ndarray. Values are converted to floats internally. Make sure all x-component values are in the range [0.0, 1.0]. The default value is None. :param resample: Determines whether to resample the points defining the Airfoil's outline. This applies to points passed in by the user or to those from the airfoils directory. I highly recommended setting this to True. Can be a bool or a numpy bool and will be converted internally to a bool. The default is True. :param n_points_per_side: The number of points to use when creating the Airfoil's MCL and when resampling the upper and lower parts of the Airfoil's outline. It must be a positive int greater than or equal to 3. The resampled outline will have a total number of points equal to (2 * n_points_per_side) - 1. I highly recommend setting this to at least 100. The default value is 400. :return: None """ ``` -------------------------------- ### Python Common Docstring Phrases Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md A collection of frequently used phrases for writing Python docstrings, categorized for module-level descriptions, array parameters, boolean parameters, return values, function descriptions, units, ranges, and coordinate systems. ```python # Module level """Contains the . """ """Contains the following subpackages:""" """Contains the following directories:""" """Contains the following modules:""" """Contains the following classes:""" """Contains the following functions:""" # Array parameters ":param name: A (shape) ndarray of dtype representing..." ":param name: An array-like object of numbers (int or float) with shape..." # Boolean parameters (accepting numpy bools) ":param name: A bool that... Can be a bool or a numpy bool and will be converted internally to a bool." # Return values ":return: A (shape) ndarray of dtype that..." ":return: A list of N (shape) ndarrays..." ":return: None" # Function descriptions (avoid "This function/method") "Takes in... and returns..." "Calculates..." "Returns..." "Validates..." # Units and ranges "The units are meters." "The values are normalized from 0.0 to 1.0 and are unitless." "It must be in the range [0.0, 1.0]." "It must be a positive int." # Coordinate systems "(in geometry axes, relative to the CG)" "(in wing axes, relative to the leading edge root point)" "(in airfoil axes, relative to the leading point)" ``` -------------------------------- ### Python Function and Method Docstring Structure Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Defines the standard reStructuredText (rST) format for function and method docstrings. Includes a short description, an optional longer description, and parameter/return value documentation using `:param:` and `:return:` tags. ```python def function_name( param1: Type1, param2: Type2, param3: Type3, ) -> ReturnType: """Short description of what the function does. Optional longer description providing more context. This provides detailed explanations of the function's behavior. It can be one or more paragraphs. Optional citation block: **Citation:** Adapted from (can be more specific if the whole function wasn't adapted): Author (or "Authors"): Date of retrieval (don't include if not known): :param param1: A (shape) dtype description of param1. Additional details about what it represents, valid ranges, units, etc. Can wrap to multiple lines. :param param2: Description of param2. :param param3: Description of param3. :return: A (shape) dtype description of what is returned. Additional details about the return value. """ ``` -------------------------------- ### Python Class Docstring Template Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md A comprehensive template for Python class docstrings following reStructuredText conventions. It includes a short description, lists of contained methods and subpackages/modules, an optional notes block for detailed explanations, and an optional citation block. ```python class ClassName: """Short description of the class. **Contains the following methods:** public_method_1: Short description (identical to method's docstring's short description. public_method_2: Short description (identical to method's docstring's short description. Optional notes block **Notes:** Detailed description of the class's purpose, behavior, or usage. Can be one or more paragraphs. Avoid numbered or bulleted lists. Optional citation block: **Citation:** Adapted from (can be more specific if the whole class wasn't adapted): Author (or "Authors"): Date of retrieval (don't include if not known): """ ``` -------------------------------- ### Python Module Docstring: Private Modules Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Provides a concise docstring format for private modules (e.g., `_meshing.py`). It consists of a single, brief sentence describing the module's purpose, without listing contents. ```python """Contains the function for meshing Wings.""" ``` -------------------------------- ### Run Solver and Visualize Results Source: https://context7.com/camurban/pterasoftware/llms.txt This code snippet illustrates how to execute a steady-state solver, print numerical results, and generate visualizations including lift distribution and streamlines. It also covers creating animations and plotting results over time for unsteady solvers. ```python import pterasoftware as ps # After running a solver solver = ps.steady_ring_vortex_lattice_method.SteadyRingVortexLatticeMethodSolver( steady_problem=problem ) solver.run() # Print numerical results ps.output.print_results(solver) # Draw 3D visualization with lift distribution ps.output.draw( solver=solver, scalar_type="lift", show_streamlines=True, show_wake_vortices=False, save=True, testing=False, ) # For unsteady solvers, create animation ps.output.animate( unsteady_solver=unsteady_solver, scalar_type="lift", show_wake_vortices=True, save=True, ) # Plot force and moment coefficients over time ps.output.plot_results_versus_time(unsteady_solver) ``` -------------------------------- ### Run GUI Application from Source (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/README.md Launches the experimental graphical user interface (GUI) for Ptera Software. This command is executed from the project's root directory after downloading the source code. Note that the GUI is not included in the PyPI package and is currently in beta. ```shell python gui/main.py ``` -------------------------------- ### Clone PteraSoftware Repository (Shell) Source: https://github.com/camurban/pterasoftware/blob/main/CONTRIBUTING.md Clones the PteraSoftware repository from GitHub to your local machine. This is the first step in setting up your development environment. ```shell git clone https://github.com//PteraSoftware.git cd PteraSoftware ``` -------------------------------- ### Trim Analysis for Steady Flight with Pterasoftware Source: https://context7.com/camurban/pterasoftware/llms.txt This code snippet demonstrates how to perform trim analysis for steady flight conditions using Pterasoftware. It involves defining the airplane geometry, an initial operating point, and then using the `analyze_steady_trim` function to find the trim conditions. The function allows specifying bounds for velocity, angle of attack, sideslip angle, and external forces, along with convergence parameters. The results, if successful, are printed to the console. ```python import pterasoftware as ps # Create airplane geometry airplane = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca2412"), num_spanwise_panels=16, chord=1.5, ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca2412"), Lp_Wcsp_Lpp=(0.5, 8.0, 0.5), chord=1.2, ), ], symmetric=True, num_chordwise_panels=10, ), ], weight=50.0, ) # Initial operating point guess operating_point = ps.operating_point.OperatingPoint( rho=1.225, vCg__E=12.0, alpha=3.0, beta=0.0, externalFX_W=0.0, ) problem = ps.problems.SteadyProblem( airplanes=[airplane], operating_point=operating_point ) # Find trim condition trim_results = ps.trim.analyze_steady_trim( problem=problem, solver_type="steady ring vortex lattice method", boundsVCg__E=(5.0, 25.0), alpha_bounds=(-5.0, 15.0), beta_bounds=(-10.0, 10.0), boundsExternalFX_W=(-20.0, 20.0), objective_cut_off=0.01, num_calls=100, ) if trim_results[0] is not None: vCg_trim, alpha_trim, beta_trim, externalFX_trim = trim_results print(f"Trim velocity: {vCg_trim:.2f} m/s") print(f"Trim angle of attack: {alpha_trim:.2f} degrees") print(f"Trim sideslip angle: {beta_trim:.2f} degrees") print(f"Trim external force: {externalFX_trim:.2f} N") else: print("Trim analysis failed to converge") ``` -------------------------------- ### Import Ptera Software in Python Script (Python) Source: https://github.com/camurban/pterasoftware/blob/main/README.md Imports the Ptera Software library into your Python script, aliasing it as 'ps' for convenient access to its functionalities. This is done after installing the package via pip. ```python import pterasoftware as ps ``` -------------------------------- ### Python Module-Level Docstring for Private Module Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md A concise module-level docstring for a private Python module, indicating its primary purpose which is related to meshing Wings. ```python """Contains the function for meshing Wings.""" ``` -------------------------------- ### Create Reference Airplane and Analyze Convergence Source: https://context7.com/camurban/pterasoftware/llms.txt This snippet demonstrates how to define a reference airplane with a wing and an operating point, then analyze the steady-state convergence of the mesh parameters using the ring vortex lattice method. ```python import pterasoftware as ps # Create reference airplane airplane = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), num_spanwise_panels=8, chord=1.0, ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), Lp_Wcsp_Lpp=(0.0, 6.0, 0.0), ), ], symmetric=True, num_chordwise_panels=6, ), ], ) operating_point = ps.operating_point.OperatingPoint( vCg__E=15.0, alpha=5.0, ) ref_problem = ps.problems.SteadyProblem( airplanes=[airplane], operating_point=operating_point ) # Find converged mesh parameters converged_aspect_ratio, converged_num_chordwise = ps.convergence.analyze_steady_convergence( ref_problem=ref_problem, solver_type="steady ring vortex lattice method", panel_aspect_ratio_bounds=(4, 1), num_chordwise_panels_bounds=(3, 12), convergence_criteria=5.0, ) if converged_aspect_ratio is not None: print(f"Converged panel aspect ratio: {converged_aspect_ratio}") print(f"Converged number of chordwise panels: {converged_num_chordwise}") else: print("Convergence analysis did not find converged parameters") ``` -------------------------------- ### Running Scripts Importing Ptera Software (Unix-like) Source: https://github.com/camurban/pterasoftware/blob/main/CLAUDE.md Executes a Python script located in a subdirectory (e.g., 'experimental/') that imports the Ptera Software package. Requires setting the PYTHONPATH environment variable to the project root and using the virtual environment's Python interpreter. ```Bash cd ${WORKSPACE}/experimental && PYTHONPATH="$PWD/.." ../.venv/bin/python script_name.py ``` -------------------------------- ### Type Narrowing with cast() Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Illustrates the use of typing.cast() for situations where the type checker cannot infer a type, such as with object dtype NumPy arrays. This should be used sparingly and only when necessary. ```python from typing import cast # For dtype=object arrays where we know the element type ring_vortex = cast( _aerodynamics.RingVortex, object_array[i, j], ) ``` -------------------------------- ### Run Unsteady Solver and Animate Results with Pterasoftware Source: https://context7.com/camurban/pterasoftware/llms.txt This snippet demonstrates how to initialize and run an unsteady solver using the Ring Vortex Lattice Method in Pterasoftware. It also shows how to animate the simulation results, specifically visualizing lift and wake vortices. The solver can be configured with various logging levels and wake prescription options. ```python import pterasoftware as ps # Assume 'example_problem' is a pre-defined UnsteadyProblem object solver = ps.unsteady_ring_vortex_lattice_method.UnsteadyRingVortexLatticeMethodSolver( unsteady_problem=example_problem, ) solver.run(logging_level="Warning", prescribed_wake=True) # Animate results ps.output.animate( unsteady_solver=solver, scalar_type="lift", show_wake_vortices=True, save=False, ) # Plot force and moment coefficients over time ps.output.plot_results_versus_time(solver) ``` -------------------------------- ### Python Module-Level Docstring for Public Module Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Demonstrates a module-level docstring for a public Python module. It outlines the primary classes and functions contained within the module, providing brief descriptions for each. ```python """Contains the Airfoil class. **Contains the following classes:** Airfoil: A class used to contain the Airfoil of a WingCrossSection. **Contains the following functions:** None """ ``` -------------------------------- ### Type Narrowing with Assertions Source: https://github.com/camurban/pterasoftware/blob/main/docs/TYPE_HINT_AND_DOCSTRING_STYLE.md Shows how to use assert statements to narrow down types, particularly when an attribute is guaranteed to be non-None at a certain point in the code. This is recommended when None represents a programming error. ```python def compute_forces(self): # At this point in the code, these should always be populated assert self.current_airplanes is not None for airplane in self.current_airplanes: # mypy now knows current_airplanes is not None ... ``` -------------------------------- ### Create Airplane and Run Steady Flow Simulation with Ring VLM Source: https://context7.com/camurban/pterasoftware/llms.txt This snippet demonstrates how to define an airplane's geometry, including its wings and airfoils, and then set up and run a steady-state aerodynamic simulation using the Steady Ring Vortex Lattice Method. It visualizes the lift distribution. ```python import pterasoftware as ps # Create airplane (same as horseshoe example) airplane = ps.geometry.airplane.Airplane( wings=[ ps.geometry.wing.Wing( wing_cross_sections=[ ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), num_spanwise_panels=12, chord=1.0, spanwise_spacing="uniform", ), ps.geometry.wing_cross_section.WingCrossSection( airfoil=ps.geometry.airfoil.Airfoil(name="naca0012"), Lp_Wcsp_Lpp=(0.0, 4.0, 0.0), ), ], symmetric=True, num_chordwise_panels=8, ), ], ) operating_point = ps.operating_point.OperatingPoint( rho=1.225, vCg__E=15.0, alpha=3.0, beta=0.0, ) problem = ps.problems.SteadyProblem( airplanes=[airplane], operating_point=operating_point ) # Use ring VLM solver instead solver = ps.steady_ring_vortex_lattice_method.SteadyRingVortexLatticeMethodSolver( steady_problem=problem ) solver.run(logging_level="Warning") ps.output.draw(solver=solver, scalar_type="lift") ```