Unsteady Solver Trim Analysis

"""Demonstrates finding the trim condition for an unsteady simulation.

The script will likely take several minutes to run, and will log trim progress and
results in a log file.
"""

import logging

import pterasoftware as ps

# Configure logging to write info level messages to a file. To display log messages on
# the console instead, omit the handler argument.
ps.set_up_logging(level="Info", handler=logging.FileHandler("example_trim.log"))

# Create an Airplane. We must specify a weight (in Newtons) for the Airplane. We will
# later find a trim condition where the weight is exactly balanced by lift.
trim_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=5,
                    control_surface_symmetry_type="symmetric",
                    spanwise_spacing="cosine",
                ),
                ps.geometry.wing_cross_section.WingCrossSection(
                    airfoil=ps.geometry.airfoil.Airfoil(
                        name="naca2412",
                    ),
                    num_spanwise_panels=None,
                    Lp_Wcsp_Lpp=(0.0, 5.0, 0.0),
                    control_surface_symmetry_type="symmetric",
                    spanwise_spacing=None,
                ),
            ],
            symmetric=True,
            symmetryNormal_G=(0, 1, 0),
            symmetryPoint_G_Cg=(0, 0, 0),
            num_chordwise_panels=5,
        ),
        ps.geometry.wing.Wing(
            wing_cross_sections=[
                ps.geometry.wing_cross_section.WingCrossSection(
                    airfoil=ps.geometry.airfoil.Airfoil(
                        name="naca0012",
                    ),
                    num_spanwise_panels=5,
                    control_surface_symmetry_type="symmetric",
                    spanwise_spacing="cosine",
                ),
                ps.geometry.wing_cross_section.WingCrossSection(
                    airfoil=ps.geometry.airfoil.Airfoil(
                        name="naca0012",
                    ),
                    num_spanwise_panels=None,
                    Lp_Wcsp_Lpp=(0.0, 1.0, 0.0),
                    control_surface_symmetry_type="symmetric",
                ),
            ],
            Ler_Gs_Cgs=(10, 0, 0),
            angles_Gs_to_Wn_ixyz=(0.0, -5.0, 0.0),
            symmetric=True,
            symmetryNormal_G=(0, 1, 0),
            symmetryPoint_G_Cg=(0, 0, 0),
            num_chordwise_panels=5,
        ),
    ],
    weight=420,
)

# Create an AirplaneMovement for this example's Airplane.
trim_airplane_movement = ps.movements.airplane_movement.AirplaneMovement(
    base_airplane=trim_airplane,
    wing_movements=[
        ps.movements.wing_movement.WingMovement(
            base_wing=trim_airplane.wings[0],
            wing_cross_section_movements=[
                ps.movements.wing_cross_section_movement.WingCrossSectionMovement(
                    base_wing_cross_section=trim_airplane.wings[0].wing_cross_sections[
                        0
                    ]
                ),
                ps.movements.wing_cross_section_movement.WingCrossSectionMovement(
                    base_wing_cross_section=trim_airplane.wings[0].wing_cross_sections[
                        1
                    ]
                ),
            ],
        ),
        ps.movements.wing_movement.WingMovement(
            base_wing=trim_airplane.wings[1],
            wing_cross_section_movements=[
                ps.movements.wing_cross_section_movement.WingCrossSectionMovement(
                    base_wing_cross_section=trim_airplane.wings[1].wing_cross_sections[
                        0
                    ]
                ),
                ps.movements.wing_cross_section_movement.WingCrossSectionMovement(
                    base_wing_cross_section=trim_airplane.wings[1].wing_cross_sections[
                        1
                    ]
                ),
            ],
        ),
    ],
)

# Create an OperatingPoint using default values.
trim_operating_point = ps.operating_point.OperatingPoint(
    externalFX_W=7.5,
)

# Create an OperatingPointMovement using default values.
trim_operating_point_movement = (
    ps.movements.operating_point_movement.OperatingPointMovement(
        base_operating_point=trim_operating_point
    )
)

trim_movement = ps.movements.movement.Movement(
    airplane_movements=[trim_airplane_movement],
    operating_point_movement=trim_operating_point_movement,
    num_chords=5,
)

trim_problem = ps.problems.UnsteadyProblem(
    movement=trim_movement,
    only_final_results=True,
)

# Call the analyze_unsteady_trim function to search for a trim condition (thrust
# balances drag, weight balances lift, and all moments are close to zero) within a
# certain set of bounds.
trim_conditions = ps.trim.analyze_unsteady_trim(
    problem=trim_problem,
    boundsVCg__E=(5, 15),
    alpha_bounds=(-10, 10),
    beta_bounds=(-0.1, 0.1),
    boundsExternalFX_W=(5, 15),
    objective_cut_off=0.025,
    num_calls=100,
    show_solver_progress=False,
)

Output

Trim log
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |Starting local search
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.0 m/s, alpha = 5.00 deg, beta = 0.00 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.156
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.0 m/s, alpha = 5.00 deg, beta = 0.00 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.155
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.0 m/s, alpha = 5.01 deg, beta = 0.00 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.156
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.0 m/s, alpha = 5.00 deg, beta = 0.0100 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.156
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.0 m/s, alpha = 5.00 deg, beta = 0.00 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.156
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.1 m/s, alpha = 4.99 deg, beta = -1.71E-07 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.151
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.1 m/s, alpha = 4.99 deg, beta = -1.71E-07 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.150
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.1 m/s, alpha = 5.00 deg, beta = -1.71E-07 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.151
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.1 m/s, alpha = 4.99 deg, beta = 0.0100 deg, externalFX_W = 7.50 N
INFO    |trim                                        |    Objective: 0.151
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 10.1 m/s, alpha = 4.99 deg, beta = -1.71E-07 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.151
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.5 m/s, alpha = 3.68 deg, beta = -2.59E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0657
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.5 m/s, alpha = 3.68 deg, beta = -2.59E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0660
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.5 m/s, alpha = 3.69 deg, beta = -2.59E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0668
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.5 m/s, alpha = 3.68 deg, beta = 0.00997 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0657
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.5 m/s, alpha = 3.68 deg, beta = -2.59E-05 deg, externalFX_W = 7.52 N
INFO    |trim                                        |    Objective: 0.0657
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 15.0 m/s, alpha = 0.588 deg, beta = -5.16E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.235
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 15.0 m/s, alpha = 0.588 deg, beta = -5.16E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.235
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 15.0 m/s, alpha = 0.598 deg, beta = -5.16E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.234
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 15.0 m/s, alpha = 0.588 deg, beta = 0.00995 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.235
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 15.0 m/s, alpha = 0.588 deg, beta = -5.16E-05 deg, externalFX_W = 7.52 N
INFO    |trim                                        |    Objective: 0.235
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.8 m/s, alpha = 3.02 deg, beta = -3.14E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0327
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.8 m/s, alpha = 3.02 deg, beta = -3.14E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0329
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.8 m/s, alpha = 3.03 deg, beta = -3.14E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0325
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.8 m/s, alpha = 3.02 deg, beta = 0.00997 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0327
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 13.8 m/s, alpha = 3.02 deg, beta = -3.14E-05 deg, externalFX_W = 7.52 N
INFO    |trim                                        |    Objective: 0.0327
INFO    |movements.movement                          |Starting analytical delta_time optimization
INFO    |movements.movement                          |Returning the initial delta_time estimate because all motion is static
INFO    |trim                                        |  State: vCg__E = 12.6 m/s, alpha = 3.18 deg, beta = -2.22E-05 deg, externalFX_W = 7.51 N
INFO    |trim                                        |    Objective: 0.0177
INFO    |trim                                        |Acceptable value reached with local search